file-utils JS文件操作工具库

file-utils 文件操作工具库

一个轻量级的文件操作工具库,提供常用的文件处理功能,支持多种文件格式,开箱即用,并针对现代前端开发进行了 Tree Shaking 优化。

支持以下特性:

  • 文件读取:支持读取文本、二进制数据、Data URL 等
  • 文件下载:支持从 URL、Blob、Base64 等多种方式下载文件
  • 文件转换:支持文件格式转换(如 Base64 转 Blob、File 转 Base64 等)
  • 文件压缩:支持将多个文件打包为 ZIP 压缩包
  • 文件压缩:支持图片压缩处理
  • 文件生成:支持生成 TXT、CSV、JSON 格式文件,可选择返回 File 对象而不下载
  • 文件验证:提供完整的文件验证和类型判断功能
  • 剪贴板操作:支持一键复制文本到剪贴板,并支持成功/失败回调
  • 辅助工具:提供深拷贝、UUID 生成、URL 参数解析、对象转 FormData 等实用工具
  • 正则验证:提供邮箱、手机、URL、坐标等多种表单验证功能
  • 自动清理:自动管理临时创建的 Blob URL,防止内存泄漏
  • TypeScript:完善的类型定义支持

方法列表

文件读取

  • readFile - 读取文件内容为文本、ArrayBuffer 或 DataURL
  • readTxtFile - 读取 TXT 文件内容
  • readCsvFile - 读取 CSV 文件并解析为对象数组
  • readJsonFile - 读取 JSON 文件并解析为 JavaScript 对象

文件下载

  • downloadFile - 从 URL 下载文件
  • downloadBlob - 下载 Blob 对象
  • downloadBase64 - 下载 Base64 编码的文件
  • downloadMultiple - 批量下载多个文件

文件转换

  • fileToBase64 - 将 File/Blob 转换为 Base64
  • base64ToBlob - 将 Base64 转换为 Blob
  • blobToFile - 将 Blob 转换为指定文件名的 File
  • base64ToFile - 将 Base64 转换为 File
  • imageUrlToBase64 - 将图片 URL 转换为 Base64
  • fileChangedImageDPI - 修改图片的 DPI 分辨率
  • compressImage - 压缩图片

文件压缩

  • fileListToZip - 将文件列表打包为 ZIP
  • downloadFileListAsZip - 下载文件列表的 ZIP 压缩包

文件生成

  • generateTxtFile - 生成 TXT 文件
  • generateCsvFile - 生成 CSV 文件
  • generateJsonFile - 生成 JSON 文件

文件验证

  • checkFileType - 检查文件类型
  • checkFileSize - 检查文件大小
  • isImage - 判断是否为图片
  • getImageDimensions - 获取图片尺寸
  • validateFile - 综合文件验证
  • formatFileSize - 格式化文件大小显示
  • getFileNameSuffix - 获取文件扩展名(不含点号)
  • getFileNamePrefix - 获取文件名(不含扩展名)
  • getFileInfo - 获取文件完整信息

剪贴板操作

  • copyToClipboard - 复制文本到剪贴板
  • pasteFromClipboard - 从剪贴板读取文本

辅助工具

  • deepClone - 深拷贝对象和数组
  • numberFixed - 数字保留指定小数位
  • parseUrlParams - 解析 URL 参数为对象
  • objectToFormData - 对象转换为 FormData
  • omitKeys - 从对象中移除指定的键
  • generateUUID - 生成 UUID(支持移除横杠)
  • arraySum - 数字数组求和
  • formatAmount - 格式化金额(千分位)
  • maskString - 字符串中间部分替换为星号
  • formatPhone - 格式化手机号码(隐藏中间 4 位)
  • arrayStringFormatNumber - 字符串数组转数值数组
  • arrayCustomSort - 自定义排序(按指定 id 顺序)
  • jsonConvertTreeList - 扁平数据转树形结构
  • jsonConvertGeneralList - 树形结构转扁平数据

正则验证 (VerifyUtils)

  • VerifyUtils.isEmail - 邮箱验证
  • VerifyUtils.isNumber - 数字验证
  • VerifyUtils.isPhone - 手机号验证
  • VerifyUtils.isUrl - URL 链接验证
  • VerifyUtils.isIP - IP 地址验证
  • VerifyUtils.isNoSpace - 无空格验证
  • VerifyUtils.isChinese - 中文验证
  • VerifyUtils.isPassword - 密码强度验证
  • VerifyUtils.isLongitude - 经度验证
  • VerifyUtils.isLatitude - 纬度验证
  • VerifyUtils.isInputCoordinates - 坐标串验证
  • VerifyUtils.isEmpty - 空值检查
  • VerifyUtils.getRule - 生成表单验证规则
  • VerifyUtils.validate - 带错误消息的验证

安装

你可以通过 npm 安装该库:

bash 复制代码
pnpm install @giszhc/file-utils

使用场景

1. 授权下载 - 需要 Token 的 API 接口

ts 复制代码
import { downloadFile } from '@giszhc/file-utils';

// 从需要授权的 API 下载文件
const token = localStorage.getItem('access_token');
await downloadFile('https://api.example.com/file/123', undefined, {
  fetchOptions: {
    headers: {
      'Authorization': `Bearer ${token}`
    }
  }
});

2. POST 请求下载 - 提交参数后获取文件

ts 复制代码
import { downloadFile } from '@giszhc/file-utils';

// 通过 POST 请求提交参数后下载文件
await downloadFile('https://api.example.com/export', 'report.xlsx', {
  fetchOptions: {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      startDate: '2024-01-01',
      endDate: '2024-12-31',
      format: 'xlsx'
    })
  }
});

3. 自定义请求头 - 添加追踪或认证信息

ts 复制代码
import { downloadFile } from '@giszhc/file-utils';

// 添加自定义请求头
await downloadFile('https://cdn.example.com/resource/file.zip', undefined, {
  fetchOptions: {
    headers: {
      'X-API-Key': 'your-api-key-here',
      'X-Request-ID': 'unique-request-id',
      'X-User-Agent': 'MyApp/1.0.0'
    }
  }
});

4. 文件上传前预览和压缩

ts 复制代码
import { fileToBase64, compressImage } from '@giszhc/file-utils';

const handleFileSelect = async (e: Event) => {
  const input = e.target as HTMLInputElement;
  const file = input.files?.[0];
  
  if (file) {
    // 压缩图片
    const compressed = await compressImage(file, {
      quality: 0.8,
      maxWidth: 1920
    });
    
    // 转换为 Base64 用于预览
    const previewUrl = await fileToBase64(compressed);
    
    // 显示预览
    const img = document.querySelector('#preview');
    img.src = previewUrl;
  }
};

5. 批量下载文件

ts 复制代码
import { downloadMultiple } from '@giszhc/file-utils';

// 批量下载多个文件,间隔 1 秒
const imageUrls = [
  'https://example.com/image1.jpg',
  'https://example.com/image2.jpg',
  'https://example.com/image3.jpg'
];

await downloadMultiple(imageUrls, 1000);

6. 文件大小格式化显示

ts 复制代码
import { getFileInfo, formatFileSize } from '@giszhc/file-utils';

const handleFileSelect = (e: Event) => {
  const input = e.target as HTMLInputElement;
  const file = input.files?.[0];
  
  if (file) {
    const info = getFileInfo(file);
    console.log(`文件名:${info.name}`);
    console.log(`类型:${info.type}`);
    console.log(`大小:${formatFileSize(info.size)}`); // 如:"2.5 MB"
    console.log(`修改时间:${new Date(info.lastModified).toLocaleString()}`);
  }
};

7. Base64 与 Blob 互转

ts 复制代码
import { base64ToBlob, fileToBase64, downloadBase64 } from '@giszhc/file-utils';

// File/Blob 转 Base64
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files?.[0];
const base64 = await fileToBase64(file);

// Base64 转 Blob 并下载
const blob = base64ToBlob(base64);
downloadBase64(base64, 'downloaded-file.png');

8. 生成 TXT 文件

ts 复制代码
import { generateTxtFile } from '@giszhc/file-utils';

// 生成简单的文本文件
generateTxtFile('Hello World!', 'hello.txt');

// 生成多行文本
const lines = ['第一行', '第二行', '第三行'].join('\n');
generateTxtFile(lines, 'multiline.txt');

// 生成文件但不下载,返回 File 对象
const file = generateTxtFile('Hello World!', 'hello.txt', { download: false });
console.log(file.name); // "hello.txt"
console.log(file.type); // "text/plain;charset=utf-8"
console.log(file.size); // 文件大小(字节)

9. 生成 CSV 文件

ts 复制代码
import { generateCsvFile } from '@giszhc/file-utils';

// 使用对象数组生成 CSV
const users = [
  { name: '张三', age: 25, city: '北京' },
  { name: '李四', age: 30, city: '上海' },
  { name: '王五', age: 28, city: '广州' }
];
generateCsvFile(users, 'users.csv');

// 使用二维数组生成 CSV
const data = [
  ['姓名', '年龄', '城市'],
  ['张三', 25, '北京'],
  ['李四', 30, '上海']
];
generateCsvFile(data, 'data.csv');

// 自定义分隔符(制表符 TSV)
generateCsvFile(data, 'data.tsv', { separator: '\t' });

// 生成文件但不下载,返回 File 对象
const csvFile = generateCsvFile(users, 'users.csv', { download: false });
console.log(csvFile.name); // "users.csv"
console.log(csvFile.type); // "text/csv;charset=utf-8"
console.log(csvFile.size); // 文件大小(字节)

10. 生成 JSON 文件

ts 复制代码
import { generateJsonFile } from '@giszhc/file-utils';

// 生成简单的 JSON 文件
const data = { name: '张三', age: 25 };
generateJsonFile(data, 'user.json');

// 生成格式化的 JSON 数组
const users = [
  { name: '张三', age: 25 },
  { name: '李四', age: 30 }
];
generateJsonFile(users, 'users.json');

// 压缩输出(不格式化)
generateJsonFile(data, 'data.min.json', { pretty: false });

// 自定义缩进
generateJsonFile(data, 'data.json', { spaces: 4 });

// 生成文件但不下载,返回 File 对象
const file = generateJsonFile(data, 'user.json', { download: false });
console.log(file.name); // "user.json"
console.log(file.type); // "application/json;charset=utf-8"
console.log(file.size); // 文件大小(字节)

11. 获取文件扩展名和文件名

ts 复制代码
import { getFileNameSuffix, getFileNamePrefix } from '@giszhc/file-utils';

const file = new File(['content'], 'document.pdf', { type: 'application/pdf' });

// 获取扩展名(不含点号)
const ext = getFileNameSuffix(file); // "pdf"

// 获取文件名(不含扩展名)
const name = getFileNamePrefix(file); // "document"

12. 文件类型验证

ts 复制代码
import { checkFileType, isImage } from '@giszhc/file-utils';

// 检查是否为 JPEG 图片
const isJpeg = checkFileType(file, ['image/jpeg']);

// 检查是否为图片或 PDF
const isValid = checkFileType(file, ['image/*', 'application/pdf']);

// 使用扩展名检查
const isAllowed = checkFileType(file, ['.jpg', '.png', '.gif']);

// 快速判断是否为图片
if (isImage(file)) {
  console.log('这是一个图片文件');
}

13. 文件大小验证

ts 复制代码
import { checkFileSize } from '@giszhc/file-utils';

// 限制不超过 2MB
const isValidSize = checkFileSize(file, 2 * 1024 * 1024);

if (!isValidSize) {
  console.log('文件过大,不能超过 2MB');
}

14. 获取图片尺寸

ts 复制代码
import { getImageDimensions } from '@giszhc/file-utils';

// 异步获取图片原始尺寸
const dimensions = await getImageDimensions(file);
console.log(`图片尺寸:${dimensions.width} x ${dimensions.height}`);

15. 综合文件验证

ts 复制代码
import { validateFile } from '@giszhc/file-utils';

// 在上传前进行全面验证
const result = await validateFile(file, {
  acceptTypes: ['image/jpeg', 'image/png'],
  maxSize: 2 * 1024 * 1024, // 2MB
  mustBeImage: true,
  minWidth: 800,
  maxWidth: 4096,
  minHeight: 600,
  maxHeight: 4096
});

if (!result.valid) {
  // 显示所有错误信息
  result.errors.forEach(error => console.error(error));
} else {
  // 验证通过,可以上传
  console.log('文件验证通过');
}

16. 读取 TXT 文件

ts 复制代码
import { readTxtFile } from '@giszhc/file-utils';

// 读取文本文件
const content = await readTxtFile(file);
console.log(content);

17. 读取 CSV 文件

ts 复制代码
import { readCsvFile } from '@giszhc/file-utils';

// 读取 CSV 文件(自动解析为对象数组)
const data = await readCsvFile(file);
console.log(data); // [{name: '张三', age: '25'}, ...]

// 自定义分隔符
const tsvData = await readCsvFile(file, { separator: '\t' });

// 不包含表头
const arrayData = await readCsvFile(file, { hasHeader: false });

18. 读取 JSON 文件

ts 复制代码
import { readJsonFile } from '@giszhc/file-utils';

// 读取 JSON 文件
const data = await readJsonFile<{ name: string; age: number }>(file);
console.log(data.name);
console.log(data.age);

19. 一键复制文本到剪贴板

ts 复制代码
import { copyToClipboard } from '@giszhc/file-utils';

// 基本使用
await copyToClipboard('Hello World!');

// 带回调的使用
await copyToClipboard('这是一段文本', {
  onSuccess: () => console.log('复制成功!'),
  onError: (error) => console.error('复制失败:', error)
});

20. 从剪贴板读取文本

ts 复制代码
import { pasteFromClipboard } from '@giszhc/file-utils';

// 读取剪贴板内容
const text = await pasteFromClipboard();
console.log('剪贴板内容:', text);

21. 深拷贝对象

ts 复制代码
import { deepClone } from '@giszhc/file-utils';

// 深拷贝对象
const obj = { a: 1, b: { c: 2 }, d: [1, 2, 3] };
const copy = deepClone(obj);
copy.b.c = 3;
console.log(obj.b.c); // 2 (原对象不受影响)

// 支持 Date、RegExp 等特殊类型
const data = {
  date: new Date(),
  regex: /test/g,
  nested: { array: [1, 2, 3] }
};
const cloned = deepClone(data);

22. 数字保留小数位

ts 复制代码
import { numberFixed } from '@giszhc/file-utils';

// 保留 2 位小数(默认)
const num1 = numberFixed(3.14159); // 3.14

// 自定义小数位数
const num2 = numberFixed(10, 3); // 10
const num3 = numberFixed(2.5678, 1); // 2.6

23. 解析 URL 参数

ts 复制代码
import { parseUrlParams } from '@giszhc/file-utils';

// 解析当前页面 URL 参数
const params = parseUrlParams();
console.log(params.id); // 从当前 URL 获取 id 参数

// 解析指定 URL 参数
const url = 'https://example.com?name=John&age=30';
const urlParams = parseUrlParams(url);
// { name: 'John', age: '30' }

24. 对象转 FormData

ts 复制代码
import { objectToFormData } from '@giszhc/file-utils';

// 简单对象转换
const obj = { name: 'John', age: 30 };
const formData = objectToFormData(obj);

// 嵌套对象
const user = {
  name: 'John',
  profile: {
    email: 'john@example.com',
    phone: '123456'
  }
};
const fd = objectToFormData(user);

// 包含文件
const fileInput = document.querySelector('input[type="file"]');
const data = {
  avatar: fileInput.files[0],
  description: 'User avatar'
};
const fdWithFile = objectToFormData(data);

25. 移除对象的特定键

ts 复制代码
import { omitKeys } from '@giszhc/file-utils';

// 移除指定的键
const obj = { a: 1, b: 2, c: 3, d: 4 };
const result = omitKeys(obj, ['b', 'd']);
// { a: 1, c: 3 }

// 反向操作:只保留指定的键
const filtered = omitKeys(obj, ['a', 'c'], true);
// { a: 1, c: 3 }

26. 生成 UUID

ts 复制代码
import { generateUUID } from '@giszhc/file-utils';

// 生成带横杠的 UUID(默认)
const uuid1 = generateUUID();
// "550e8400-e29b-41d4-a716-446655440000"

// 生成不带横杠的 UUID
const uuid2 = generateUUID(true);
// "550e8400e29b41d4a716446655440000"

// 使用场景:生成唯一 ID
const userId = generateUUID();
const requestId = generateUUID(true); // 无横杠版本用于数据库存储

27. 正则验证工具类

ts 复制代码
import { VerifyUtils } from '@giszhc/file-utils';

// 基础验证
VerifyUtils.isEmail('test@example.com'); // true
VerifyUtils.isPhone('13800138000'); // true
VerifyUtils.isUrl('https://example.com'); // true
VerifyUtils.isNumber('123.45'); // true
VerifyUtils.isNoSpace('hello'); // true
VerifyUtils.isChinese('你好'); // true
VerifyUtils.isPassword('Abc@1234'); // true

// 经纬度验证
VerifyUtils.isLongitude(116.4); // true
VerifyUtils.isLatitude(39.9); // true

// 坐标串验证(支持多级分隔符)
VerifyUtils.isInputCoordinates('116.4,39.9'); // true
VerifyUtils.isInputCoordinates('116.4,39.9;117.4,40.9'); // true
VerifyUtils.isInputCoordinates('116.4,39.9|117.4,40.9'); // true

// 空值检查
VerifyUtils.isEmpty(''); // true
VerifyUtils.isEmpty(null); // true
VerifyUtils.isEmpty([]); // true
VerifyUtils.isEmpty({}); // true

// 生成 Element UI 表单验证规则
const rules = {
  email: [
    { required: true, message: '请输入邮箱', trigger: 'blur' },
    VerifyUtils.getRule('email', 'blur')
  ],
  phone: [
    { required: true, message: '请输入手机号', trigger: 'blur' },
    VerifyUtils.getRule('phone', 'blur')
  ],
  url: [VerifyUtils.getRule('url')]
};

// 获取错误提示语
console.log(VerifyUtils.messages.email); // "请输入正确的邮箱地址"

使用方法

readFile(file: File | Blob, type?: string): Promise<string | ArrayBuffer>

读取文件内容。支持读取文本、ArrayBuffer、Data URL 等多种格式。

ts 复制代码
import { readFile } from '@giszhc/file-utils';

// 读取文本文件
const handleTextFile = async (file: File) => {
    const content = await readFile(file, 'text');
    console.log(content);
};

// 读取为 ArrayBuffer
const handleBinaryFile = async (file: File) => {
    const buffer = await readFile(file, 'arrayBuffer');
    console.log(buffer);
};

// 读取为 Data URL (Base64)
const handleDataUrl = async (file: File) => {
    const dataUrl = await readFile(file, 'dataURL');
    console.log(dataUrl);
};

readTxtFile(file: File | Blob, encoding?: string): Promise

读取 TXT 文件,返回纯文本内容。

ts 复制代码
import { readTxtFile } from '@giszhc/file-utils';

const content = await readTxtFile(file);
console.log(content);

readCsvFile(file: File | Blob, options?: CsvOptions): Promise<any[]>

读取 CSV 文件,自动解析为对象数组或二维数组。

ts 复制代码
import { readCsvFile } from '@giszhc/file-utils';

// 读取为对象数组(假设有表头)
const data = await readCsvFile(file);
data.forEach(row => {
    console.log(row.name, row.age);
});

// 自定义分隔符(TSV)
const tsvData = await readCsvFile(file, { separator: '\t' });

// 不包含表头,返回二维数组
const arrayData = await readCsvFile(file, { hasHeader: false });

readJsonFile(file: File | Blob): Promise

读取 JSON 文件,返回解析后的 JavaScript 对象,支持泛型类型定义。

ts 复制代码
import { readJsonFile } from '@giszhc/file-utils';

// 读取 JSON 配置
const config = await readJsonFile<{ apiEndpoint: string; version: string }>(file);
console.log(config.apiEndpoint);

// 读取用户数据
const user = await readJsonFile<{ name: string; email: string }>(file);
console.log(user.name);

downloadFile(url: string, filename?: string): Promise

从 URL 下载文件。支持跨域下载(需服务器支持 CORS)。

ts 复制代码
import { downloadFile } from '@giszhc/file-utils';

// 下载文件并指定文件名
await downloadFile('https://example.com/file.pdf', 'my-file.pdf');

// 使用默认文件名
await downloadFile('https://example.com/image.jpg');

downloadBlob(blob: Blob, filename: string): void

下载 Blob 对象。

ts 复制代码
import { downloadBlob } from '@giszhc/file-utils';

const blob = new Blob(['Hello World'], { type: 'text/plain' });
downloadBlob(blob, 'hello.txt');

downloadBase64(base64: string, filename: string, mimeType?: string): void

下载 Base64 编码的文件。

ts 复制代码
import { downloadBase64 } from '@giszhc/file-utils';

const base64Data = 'data:image/png;base64,iVBORw0KGgoAAAANS...';
downloadBase64(base64Data, 'image.png');

fileToBase64(file: File | Blob): Promise

将 File 或 Blob 对象转换为 Base64 编码。

ts 复制代码
import { fileToBase64 } from '@giszhc/file-utils';

const input = document.querySelector('input[type="file"]');
input.addEventListener('change', async (e) => {
    const file = e.target.files[0];
    const base64 = await fileToBase64(file);
    console.log(base64);
});

base64ToBlob(base64: string, mimeType?: string): Blob

将 Base64 编码转换为 Blob 对象。

ts 复制代码
import { base64ToBlob } from '@giszhc/file-utils';

const base64 = 'data:image/png;base64,iVBORw0KGgoAAAANS...';
const blob = base64ToBlob(base64);

base64ToFile(base64: string, filename?: string, mimeType?: string): File

将 Base64 编码转换为 File 对象。

ts 复制代码
import { base64ToFile } from '@giszhc/file-utils';

// 转换带前缀的 Base64
const base64 = 'data:image/png;base64,iVBORw0KGgoAAAANS...';
const file = base64ToFile(base64, 'image.png');
console.log(file.name); // "image.png"

// 转换不带前缀的 Base64
const pureBase64 = 'iVBORw0KGgoAAAANS...';
const file2 = base64ToFile(pureBase64, 'image.png', 'image/png');

imageUrlToBase64(imageUrl: string, mimeType?: string, quality?: number): Promise

将图片 URL 转换为 Base64 编码。使用 Canvas 将图片绘制后转换为 Base64。

ts 复制代码
import { imageUrlToBase64 } from '@giszhc/file-utils';

// 转换远程图片
const base64 = await imageUrlToBase64('https://example.com/image.jpg');
console.log(base64); // data:image/png;base64,...

// 转换为 JPEG 格式,80% 质量
const jpegBase64 = await imageUrlToBase64(
    'https://example.com/image.png',
    'image/jpeg',
    0.8
);

fileChangedImageDPI(source: string | Blob, dpi?: number): Promise<string | Blob>

修改图片的分辨率 DPI(每英寸点数)。支持 Base64 字符串和 Blob 对象。返回 Promise。

ts 复制代码
import { fileChangedImageDPI } from '@giszhc/file-utils';

// 修改 Base64 图片的 DPI 为 300(适合打印)
const base64 = 'data:image/png;base64,iVBORw0KGgoAAAANS...';
const highDpiBase64 = await fileChangedImageDPI(base64, 300);
console.log('高分辨率图片:', highDpiBase64);

// 修改 Blob 图片的 DPI
const blob = new Blob([imageData], { type: 'image/png' });
const newBlob = await fileChangedImageDPI(blob, 300);
// newBlob 是修改后的 Blob 对象

// 使用默认 DPI (96,屏幕显示标准)
const defaultDpiResult = await fileChangedImageDPI(base64);

// 设置为 72 DPI(网页优化)
const webOptimized = await fileChangedImageDPI(base64, 72);

// 结合其他方法使用
import { fileToBase64, base64ToBlob, fileChangedImageDPI } from '@giszhc/file-utils';

const handleImageUpload = async (file: File) => {
    // 方式 1: 使用 Base64
    const base64 = await fileToBase64(file);
    const highResBase64 = await fileChangedImageDPI(base64, 300);
    
    // 方式 2: 直接使用 Blob
    const highResBlob = await fileChangedImageDPI(file, 300);
    const highResFile = base64ToFile(highResBase64, 'high-res.png');
};

应用场景:

  • 🖼️ 打印前提升 DPI:将网络图片的 DPI 从 72 提升到 300,获得更好的打印质量
  • 🌐 网页优化:降低 DPI 到 72,减少文件体积,加快网页加载速度
  • 📱 设备适配:根据不同设备的显示需求调整 DPI
  • 📄 出版印刷:满足专业印刷的 300 DPI 或更高要求

注意事项:

  • 该方法仅修改图片元数据中的 DPI 值,不会改变图片的像素尺寸
  • DPI 值越高,打印时的物理尺寸越小,但细节越清晰
  • 标准屏幕显示通常使用 96 DPI,印刷品通常需要 300 DPI
  • 输入类型为 Base64 时返回 Base64,输入类型为 Blob 时返回 Blob
  • 该方法是异步函数,需要使用 await 调用

compressImage(file: File, quality?: number, maxWidth?: number, maxHeight?: number): Promise

压缩图片文件。支持调整质量和最大尺寸。

ts 复制代码
import { compressImage } from '@giszhc/file-utils';

const handleImageUpload = async (file: File) => {
    // 压缩到 80% 质量,最大宽度 1920px
    const compressed = await compressImage(file, 0.8, 1920);
    
    // 使用压缩后的文件上传
    const formData = new FormData();
    formData.append('image', compressed, file.name);
};

generateTxtFile(content: string, filename: string, encoding?: string): void

生成并下载 TXT 文件。

ts 复制代码
import { generateTxtFile } from '@giszhc/file-utils';

// 生成简单的文本文件
generateTxtFile('Hello World!', 'hello.txt');

// 生成多行文本
const lines = ['第一行', '第二行', '第三行'].join('\n');
generateTxtFile(lines, 'multiline.txt');

generateCsvFile(data: Record<string, any>[] | any[][], filename: string, options?: CsvOptions): void

生成并下载 CSV 文件。支持对象数组和二维数组,自动处理表头和字段转义。

ts 复制代码
import { generateCsvFile } from '@giszhc/file-utils';

// 使用对象数组
const users = [
    { name: '张三', age: 25, city: '北京' },
    { name: '李四', age: 30, city: '上海' }
];
generateCsvFile(users, 'users.csv');

// 使用二维数组
const data = [
    ['姓名', '年龄', '城市'],
    ['张三', 25, '北京'],
    ['李四', 30, '上海']
];
generateCsvFile(data, 'data.csv');

// 自定义配置(制表符分隔、不包含表头)
generateCsvFile(data, 'data.tsv', {
    separator: '\t',
    includeHeader: false
});

generateJsonFile(data: any, filename: string, options?: JsonOptions): void

生成并下载 JSON 文件。支持格式化和压缩输出。

ts 复制代码
import { generateJsonFile } from '@giszhc/file-utils';

// 生成简单的 JSON 文件
const data = { name: '张三', age: 25 };
generateJsonFile(data, 'user.json');

// 格式化输出(默认)
const users = [
    { name: '张三', age: 25 },
    { name: '李四', age: 30 }
];
generateJsonFile(users, 'users.json');

// 压缩输出
generateJsonFile(data, 'data.min.json', { pretty: false });

// 自定义缩进
generateJsonFile(data, 'data.json', { spaces: 4 });

getFileExtension(file: File | string): string

获取文件扩展名(后缀),包含点号。

ts 复制代码
import { getFileExtension } from '@giszhc/file-utils';

const file = new File(['content'], 'document.pdf', { type: 'application/pdf' });
const ext = getFileExtension(file); // ".pdf"

// 也可以传入文件名
const ext2 = getFileExtension('image.png'); // ".png"

getFileNameWithoutExtension(file: File | string): string

获取文件名(不含扩展名)。

ts 复制代码
import { getFileNameWithoutExtension } from '@giszhc/file-utils';

const file = new File(['content'], 'archive.tar.gz', { type: 'application/gzip' });
const name = getFileNameWithoutExtension(file); // "archive.tar"

checkFileType(file: File, acceptTypes: string[]): boolean

检查文件类型是否匹配。支持 MIME 类型、通配符和扩展名。

ts 复制代码
import { checkFileType } from '@giszhc/file-utils';

// 精确匹配 MIME 类型
checkFileType(file, ['image/jpeg']);

// 使用通配符
checkFileType(file, ['image/*', 'application/pdf']);

// 使用扩展名
checkFileType(file, ['.jpg', '.png', '.gif']);

checkFileSize(file: File, maxSize: number): boolean

检查文件大小是否符合要求(字节)。

ts 复制代码
import { checkFileSize } from '@giszhc/file-utils';

// 限制不超过 2MB
const isValid = checkFileSize(file, 2 * 1024 * 1024);
if (!isValid) {
    console.log('文件过大');
}

isImage(file: File): boolean

快速判断文件是否为图片格式。

ts 复制代码
import { isImage } from '@giszhc/file-utils';

if (isImage(file)) {
    console.log('这是一个图片文件');
}

getImageDimensions(file: File): Promise<{ width: number, height: number }>

异步获取图片的原始宽高。

ts 复制代码
import { getImageDimensions } from '@giszhc/file-utils';

const dimensions = await getImageDimensions(file);
console.log(`图片尺寸:${dimensions.width} x ${dimensions.height}`);

validateFile(file: File, options?: IFileValidationOptions): Promise

综合文件验证,在上传前进行合法性检查。

ts 复制代码
import { validateFile } from '@giszhc/file-utils';

const result = await validateFile(file, {
    acceptTypes: ['image/jpeg', 'image/png'],
    maxSize: 2 * 1024 * 1024, // 2MB
    mustBeImage: true,
    minWidth: 800,
    maxWidth: 4096,
    minHeight: 600,
    maxHeight: 4096
});

if (!result.valid) {
    // 显示所有错误
    result.errors.forEach(err => console.error(err));
} else {
    console.log('验证通过');
}

arrayStringFormatNumber(arrayList: string[]): number[]

将字符串数组转换为数值数组。

ts 复制代码
import { arrayStringFormatNumber } from '@giszhc/file-utils';

// 将字符串数字数组转换为数值数组
const strArr = ["0", "1", "2", "3", "4"];
const numArr = arrayStringFormatNumber(strArr);
console.log(numArr); // [0, 1, 2, 3, 4]

// 处理带小数点的字符串
const decimalStrs = ["1.5", "2.7", "3.14"];
const decimalNums = arrayStringFormatNumber(decimalStrs);
console.log(decimalNums); // [1.5, 2.7, 3.14]

arrayCustomSort(ids: string[], dataList: any[], cbA: Function, cbB: Function): void

根据给定的 id 顺序对数据列表进行排序。

ts 复制代码
import { arrayCustomSort } from '@giszhc/file-utils';

// 基本使用
const ids = ['id1', 'id2', 'id3'];
const dataList = [
    { id: 'id3', name: 'Layer 3' },
    { id: 'id1', name: 'Layer 1' },
    { id: 'id2', name: 'Layer 2' }
];

arrayCustomSort(ids, dataList, item => item.id, item => item.id);
// 排序后:[
//   { id: 'id1', name: 'Layer 1' },
//   { id: 'id2', name: 'Layer 2' },
//   { id: 'id3', name: 'Layer 3' }
// ]

// 使用不同的回调函数处理不同类型的数据
const orderIds = ['admin', 'user', 'guest'];
const roles = [
    { roleId: 'guest', roleName: '访客' },
    { roleId: 'admin', roleName: '管理员' },
    { roleId: 'user', roleName: '普通用户' }
];

arrayCustomSort(orderIds, roles, role => role.roleId, role => role.roleId);
// 按指定顺序排序:管理员、普通用户、访客

jsonConvertTreeList(dataList: any[]): any[]

将扁平数据数组转换为树形结构。

ts 复制代码
import { jsonConvertTreeList } from '@giszhc/file-utils';

// 扁平数据
const flatData = [
    { id: 1, pid: null, name: '根节点' },
    { id: 2, pid: 1, name: '子节点 1' },
    { id: 3, pid: 1, name: '子节点 2' },
    { id: 4, pid: 2, name: '孙节点 1' }
];

const tree = jsonConvertTreeList(flatData);
/*
返回树形结构:
[
  {
    id: 1,
    pid: null,
    name: '根节点',
    children: [
      {
        id: 2,
        pid: 1,
        name: '子节点 1',
        children: [
          { id: 4, pid: 2, name: '孙节点 1' }
        ]
      },
      {
        id: 3,
        pid: 1,
        name: '子节点 2',
        children: []
      }
    ]
  }
]
*/

// 应用场景:菜单生成、组织架构展示
const menuData = [
    { id: 1, pid: null, title: '系统管理' },
    { id: 2, pid: 1, title: '用户管理' },
    { id: 3, pid: 1, title: '角色管理' },
    { id: 4, pid: 2, title: '用户列表' },
    { id: 5, pid: 2, title: '用户新增' }
];

const menuTree = jsonConvertTreeList(menuData);

jsonConvertGeneralList(treeList: any[], delChildrenField?: boolean): any[]

将树形结构转换回扁平数据数组。

ts 复制代码
import { jsonConvertGeneralList } from '@giszhc/file-utils';

// 树形结构
const tree = [
    {
        id: 1,
        pid: null,
        name: '根节点',
        children: [
            {
                id: 2,
                pid: 1,
                name: '子节点 1',
                children: [
                    { id: 4, pid: 2, name: '孙节点 1' }
                ]
            },
            {
                id: 3,
                pid: 1,
                name: '子节点 2',
                children: []
            }
        ]
    }
];

// 保留 children 字段
const flatWithChildren = jsonConvertGeneralList(tree);
console.log(flatWithChildren.length); // 4

// 删除 children 字段
const flatWithoutChildren = jsonConvertGeneralList(tree, true);
console.log(flatWithoutChildren[0]); 
// { id: 1, pid: null, name: '根节点' } (不含 children)

// 应用场景:将树形菜单保存为扁平数据存储到数据库
const menuTree = [...]; // 树形菜单
const flatMenuData = jsonConvertGeneralList(menuTree, true);
// 可以发送到后端保存到数据库

类型定义

ts 复制代码
// 文件读取类型
export type ReadFileType = 'text' | 'arrayBuffer' | 'dataURL' | 'binaryString';

// 压缩选项
export interface CompressOptions {
    quality?: number;      // 压缩质量 (0-1),默认 0.8
    maxWidth?: number;     // 最大宽度,默认无限制
    maxHeight?: number;    // 最大高度,默认无限制
    mimeType?: string;     // 输出 MIME 类型,默认 'image/jpeg'
}

// 文件验证结果
export interface IValidationResult {
    valid: boolean;        // 是否通过验证
    errors: string[];      // 错误信息列表
}

// 文件验证选项
export interface IFileValidationOptions {
    acceptTypes?: string[];   // 接受的文件类型
    maxSize?: number;         // 最大文件大小(字节)
    mustBeImage?: boolean;    // 是否必须为图片
    minWidth?: number;        // 最小宽度(图片)
    maxWidth?: number;        // 最大宽度(图片)
    minHeight?: number;       // 最小高度(图片)
    maxHeight?: number;       // 最大高度(图片)
}

注意事项

  1. 内存管理 :使用 downloadFiledownloadBlob 等方法时,库会自动清理临时创建的 Blob URL,无需手动释放
  2. CORS 限制:从 URL 下载文件时,需要目标服务器支持 CORS
  3. 浏览器兼容性:部分 API 可能需要较新的浏览器支持(如 ES2020+)
  4. 文件大小限制:读取大文件时注意浏览器内存限制

完结,撒花✿✿ヽ(°▽°)ノ✿

相关推荐
前端小咸鱼一条15 分钟前
16.迭代器 和 生成器
开发语言·前端·javascript
小陈工23 分钟前
2026年3月31日技术资讯洞察:AI智能体安全、异步编程突破与Python运行时演进
开发语言·jvm·数据库·人工智能·python·安全·oracle
ok_hahaha42 分钟前
java从头开始-黑马点评-Redission
java·开发语言
无巧不成书021842 分钟前
Java面向对象零基础实战:从Employee类吃透自定义类核心,掌握封装精髓
java·开发语言·java入门·面向对象·自定义类·employee类·java核心技术
小江的记录本1 小时前
【注解】常见 Java 注解系统性知识体系总结(附《全方位对比表》+ 思维导图)
java·前端·spring boot·后端·spring·mybatis·web
web守墓人1 小时前
【前端】记一次将ruoyi vue3 element-plus迁移到arco design vue的经历
前端·vue.js·arco design
伊步沁心1 小时前
Webpack & Vite 深度解析
前端
libokaifa1 小时前
OpenSpec + TDD:让 AI 写代码,用测试兜底
前端·ai编程
用户15815963743701 小时前
搭 AI Agent 团队踩了 18 个坑,总结出这 5 个关键步骤
前端
Kellen1 小时前
Fumadocs 基础概念:从内容源到页面渲染
前端