@giszhc/file-utils 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +710 -0
- package/dist/file-utils.js +349 -0
- package/package.json +36 -0
- package/types/convert.d.ts +37 -0
- package/types/download.d.ts +96 -0
- package/types/generate.d.ts +93 -0
- package/types/index.d.ts +44 -0
- package/types/read.d.ts +70 -0
- package/types/utils.d.ts +43 -0
- package/types/validators.d.ts +107 -0
package/README.md
ADDED
|
@@ -0,0 +1,710 @@
|
|
|
1
|
+
# file-utils 文件操作工具库
|
|
2
|
+
|
|
3
|
+
一个轻量级的文件操作工具库,提供常用的文件处理功能,支持多种文件格式,开箱即用,并针对现代前端开发进行了 Tree Shaking 优化。
|
|
4
|
+
|
|
5
|
+
支持以下特性:
|
|
6
|
+
|
|
7
|
+
- **文件读取**:支持读取文本、二进制数据、Data URL 等
|
|
8
|
+
- **文件下载**:支持从 URL、Blob、Base64 等多种方式下载文件
|
|
9
|
+
- **文件转换**:支持文件格式转换(如 Base64 转 Blob、File 转 Base64 等)
|
|
10
|
+
- **文件压缩**:支持图片压缩处理
|
|
11
|
+
- **文件生成**:支持生成 TXT、CSV、JSON 格式文件
|
|
12
|
+
- **文件验证**:提供完整的文件验证和类型判断功能
|
|
13
|
+
- **自动清理**:自动管理临时创建的 Blob URL,防止内存泄漏
|
|
14
|
+
- **TypeScript**:完善的类型定义支持
|
|
15
|
+
|
|
16
|
+
------
|
|
17
|
+
|
|
18
|
+
## 安装
|
|
19
|
+
|
|
20
|
+
你可以通过 npm 安装该库:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm install @giszhc/file-utils
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
------
|
|
27
|
+
|
|
28
|
+
## 使用场景
|
|
29
|
+
|
|
30
|
+
### 1. 授权下载 - 需要 Token 的 API 接口
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { downloadFile } from '@giszhc/file-utils';
|
|
34
|
+
|
|
35
|
+
// 从需要授权的 API 下载文件
|
|
36
|
+
const token = localStorage.getItem('access_token');
|
|
37
|
+
await downloadFile('https://api.example.com/file/123', undefined, {
|
|
38
|
+
fetchOptions: {
|
|
39
|
+
headers: {
|
|
40
|
+
'Authorization': `Bearer ${token}`
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. POST 请求下载 - 提交参数后获取文件
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { downloadFile } from '@giszhc/file-utils';
|
|
50
|
+
|
|
51
|
+
// 通过 POST 请求提交参数后下载文件
|
|
52
|
+
await downloadFile('https://api.example.com/export', 'report.xlsx', {
|
|
53
|
+
fetchOptions: {
|
|
54
|
+
method: 'POST',
|
|
55
|
+
headers: {
|
|
56
|
+
'Content-Type': 'application/json'
|
|
57
|
+
},
|
|
58
|
+
body: JSON.stringify({
|
|
59
|
+
startDate: '2024-01-01',
|
|
60
|
+
endDate: '2024-12-31',
|
|
61
|
+
format: 'xlsx'
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 3. 自定义请求头 - 添加追踪或认证信息
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { downloadFile } from '@giszhc/file-utils';
|
|
71
|
+
|
|
72
|
+
// 添加自定义请求头
|
|
73
|
+
await downloadFile('https://cdn.example.com/resource/file.zip', undefined, {
|
|
74
|
+
fetchOptions: {
|
|
75
|
+
headers: {
|
|
76
|
+
'X-API-Key': 'your-api-key-here',
|
|
77
|
+
'X-Request-ID': 'unique-request-id',
|
|
78
|
+
'X-User-Agent': 'MyApp/1.0.0'
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 4. 文件上传前预览和压缩
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { fileToBase64, compressImage } from '@giszhc/file-utils';
|
|
88
|
+
|
|
89
|
+
const handleFileSelect = async (e: Event) => {
|
|
90
|
+
const input = e.target as HTMLInputElement;
|
|
91
|
+
const file = input.files?.[0];
|
|
92
|
+
|
|
93
|
+
if (file) {
|
|
94
|
+
// 压缩图片
|
|
95
|
+
const compressed = await compressImage(file, {
|
|
96
|
+
quality: 0.8,
|
|
97
|
+
maxWidth: 1920
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// 转换为 Base64 用于预览
|
|
101
|
+
const previewUrl = await fileToBase64(compressed);
|
|
102
|
+
|
|
103
|
+
// 显示预览
|
|
104
|
+
const img = document.querySelector('#preview');
|
|
105
|
+
img.src = previewUrl;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 5. 批量下载文件
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import { downloadMultiple } from '@giszhc/file-utils';
|
|
114
|
+
|
|
115
|
+
// 批量下载多个文件,间隔 1 秒
|
|
116
|
+
const imageUrls = [
|
|
117
|
+
'https://example.com/image1.jpg',
|
|
118
|
+
'https://example.com/image2.jpg',
|
|
119
|
+
'https://example.com/image3.jpg'
|
|
120
|
+
];
|
|
121
|
+
|
|
122
|
+
await downloadMultiple(imageUrls, 1000);
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 6. 文件大小格式化显示
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { getFileInfo, formatFileSize } from '@giszhc/file-utils';
|
|
129
|
+
|
|
130
|
+
const handleFileSelect = (e: Event) => {
|
|
131
|
+
const input = e.target as HTMLInputElement;
|
|
132
|
+
const file = input.files?.[0];
|
|
133
|
+
|
|
134
|
+
if (file) {
|
|
135
|
+
const info = getFileInfo(file);
|
|
136
|
+
console.log(`文件名:${info.name}`);
|
|
137
|
+
console.log(`类型:${info.type}`);
|
|
138
|
+
console.log(`大小:${formatFileSize(info.size)}`); // 如:"2.5 MB"
|
|
139
|
+
console.log(`修改时间:${new Date(info.lastModified).toLocaleString()}`);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 7. Base64 与 Blob 互转
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import { base64ToBlob, fileToBase64, downloadBase64 } from '@giszhc/file-utils';
|
|
148
|
+
|
|
149
|
+
// File/Blob 转 Base64
|
|
150
|
+
const fileInput = document.querySelector('input[type="file"]');
|
|
151
|
+
const file = fileInput.files?.[0];
|
|
152
|
+
const base64 = await fileToBase64(file);
|
|
153
|
+
|
|
154
|
+
// Base64 转 Blob 并下载
|
|
155
|
+
const blob = base64ToBlob(base64);
|
|
156
|
+
downloadBase64(base64, 'downloaded-file.png');
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 8. 生成 TXT 文件
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
import { generateTxtFile } from '@giszhc/file-utils';
|
|
163
|
+
|
|
164
|
+
// 生成简单的文本文件
|
|
165
|
+
generateTxtFile('Hello World!', 'hello.txt');
|
|
166
|
+
|
|
167
|
+
// 生成多行文本
|
|
168
|
+
const lines = ['第一行', '第二行', '第三行'].join('\n');
|
|
169
|
+
generateTxtFile(lines, 'multiline.txt');
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 9. 生成 CSV 文件
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
import { generateCsvFile } from '@giszhc/file-utils';
|
|
176
|
+
|
|
177
|
+
// 使用对象数组生成 CSV
|
|
178
|
+
const users = [
|
|
179
|
+
{ name: '张三', age: 25, city: '北京' },
|
|
180
|
+
{ name: '李四', age: 30, city: '上海' },
|
|
181
|
+
{ name: '王五', age: 28, city: '广州' }
|
|
182
|
+
];
|
|
183
|
+
generateCsvFile(users, 'users.csv');
|
|
184
|
+
|
|
185
|
+
// 使用二维数组生成 CSV
|
|
186
|
+
const data = [
|
|
187
|
+
['姓名', '年龄', '城市'],
|
|
188
|
+
['张三', 25, '北京'],
|
|
189
|
+
['李四', 30, '上海']
|
|
190
|
+
];
|
|
191
|
+
generateCsvFile(data, 'data.csv');
|
|
192
|
+
|
|
193
|
+
// 自定义分隔符(制表符 TSV)
|
|
194
|
+
generateCsvFile(data, 'data.tsv', { separator: '\t' });
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### 10. 生成 JSON 文件
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
import { generateJsonFile } from '@giszhc/file-utils';
|
|
201
|
+
|
|
202
|
+
// 生成简单的 JSON 文件
|
|
203
|
+
const data = { name: '张三', age: 25 };
|
|
204
|
+
generateJsonFile(data, 'user.json');
|
|
205
|
+
|
|
206
|
+
// 生成格式化的 JSON 数组
|
|
207
|
+
const users = [
|
|
208
|
+
{ name: '张三', age: 25 },
|
|
209
|
+
{ name: '李四', age: 30 }
|
|
210
|
+
];
|
|
211
|
+
generateJsonFile(users, 'users.json');
|
|
212
|
+
|
|
213
|
+
// 压缩输出(不格式化)
|
|
214
|
+
generateJsonFile(data, 'data.min.json', { pretty: false });
|
|
215
|
+
|
|
216
|
+
// 自定义缩进
|
|
217
|
+
generateJsonFile(data, 'data.json', { spaces: 4 });
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### 11. 获取文件扩展名和文件名
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
import { getFileExtension, getFileNameWithoutExtension } from '@giszhc/file-utils';
|
|
224
|
+
|
|
225
|
+
const file = new File(['content'], 'document.pdf', { type: 'application/pdf' });
|
|
226
|
+
|
|
227
|
+
// 获取扩展名
|
|
228
|
+
const ext = getFileExtension(file); // ".pdf"
|
|
229
|
+
|
|
230
|
+
// 获取文件名(不含扩展名)
|
|
231
|
+
const name = getFileNameWithoutExtension(file); // "document"
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### 12. 文件类型验证
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
import { checkFileType, isImage } from '@giszhc/file-utils';
|
|
238
|
+
|
|
239
|
+
// 检查是否为 JPEG 图片
|
|
240
|
+
const isJpeg = checkFileType(file, ['image/jpeg']);
|
|
241
|
+
|
|
242
|
+
// 检查是否为图片或 PDF
|
|
243
|
+
const isValid = checkFileType(file, ['image/*', 'application/pdf']);
|
|
244
|
+
|
|
245
|
+
// 使用扩展名检查
|
|
246
|
+
const isAllowed = checkFileType(file, ['.jpg', '.png', '.gif']);
|
|
247
|
+
|
|
248
|
+
// 快速判断是否为图片
|
|
249
|
+
if (isImage(file)) {
|
|
250
|
+
console.log('这是一个图片文件');
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### 13. 文件大小验证
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
import { checkFileSize } from '@giszhc/file-utils';
|
|
258
|
+
|
|
259
|
+
// 限制不超过 2MB
|
|
260
|
+
const isValidSize = checkFileSize(file, 2 * 1024 * 1024);
|
|
261
|
+
|
|
262
|
+
if (!isValidSize) {
|
|
263
|
+
console.log('文件过大,不能超过 2MB');
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### 14. 获取图片尺寸
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
import { getImageDimensions } from '@giszhc/file-utils';
|
|
271
|
+
|
|
272
|
+
// 异步获取图片原始尺寸
|
|
273
|
+
const dimensions = await getImageDimensions(file);
|
|
274
|
+
console.log(`图片尺寸:${dimensions.width} x ${dimensions.height}`);
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### 15. 综合文件验证
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
import { validateFile } from '@giszhc/file-utils';
|
|
281
|
+
|
|
282
|
+
// 在上传前进行全面验证
|
|
283
|
+
const result = await validateFile(file, {
|
|
284
|
+
acceptTypes: ['image/jpeg', 'image/png'],
|
|
285
|
+
maxSize: 2 * 1024 * 1024, // 2MB
|
|
286
|
+
mustBeImage: true,
|
|
287
|
+
minWidth: 800,
|
|
288
|
+
maxWidth: 4096,
|
|
289
|
+
minHeight: 600,
|
|
290
|
+
maxHeight: 4096
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
if (!result.valid) {
|
|
294
|
+
// 显示所有错误信息
|
|
295
|
+
result.errors.forEach(error => console.error(error));
|
|
296
|
+
} else {
|
|
297
|
+
// 验证通过,可以上传
|
|
298
|
+
console.log('文件验证通过');
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### 16. 读取 TXT 文件
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
import { readTxtFile } from '@giszhc/file-utils';
|
|
306
|
+
|
|
307
|
+
// 读取文本文件
|
|
308
|
+
const content = await readTxtFile(file);
|
|
309
|
+
console.log(content);
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### 17. 读取 CSV 文件
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
import { readCsvFile } from '@giszhc/file-utils';
|
|
316
|
+
|
|
317
|
+
// 读取 CSV 文件(自动解析为对象数组)
|
|
318
|
+
const data = await readCsvFile(file);
|
|
319
|
+
console.log(data); // [{name: '张三', age: '25'}, ...]
|
|
320
|
+
|
|
321
|
+
// 自定义分隔符
|
|
322
|
+
const tsvData = await readCsvFile(file, { separator: '\t' });
|
|
323
|
+
|
|
324
|
+
// 不包含表头
|
|
325
|
+
const arrayData = await readCsvFile(file, { hasHeader: false });
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### 18. 读取 JSON 文件
|
|
329
|
+
|
|
330
|
+
```ts
|
|
331
|
+
import { readJsonFile } from '@giszhc/file-utils';
|
|
332
|
+
|
|
333
|
+
// 读取 JSON 文件
|
|
334
|
+
const data = await readJsonFile<{ name: string; age: number }>(file);
|
|
335
|
+
console.log(data.name);
|
|
336
|
+
console.log(data.age);
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
------
|
|
340
|
+
|
|
341
|
+
## 使用方法
|
|
342
|
+
|
|
343
|
+
### readFile(file: File | Blob, type?: string): Promise<string | ArrayBuffer>
|
|
344
|
+
|
|
345
|
+
读取文件内容。支持读取文本、ArrayBuffer、Data URL 等多种格式。
|
|
346
|
+
|
|
347
|
+
```ts
|
|
348
|
+
import { readFile } from '@giszhc/file-utils';
|
|
349
|
+
|
|
350
|
+
// 读取文本文件
|
|
351
|
+
const handleTextFile = async (file: File) => {
|
|
352
|
+
const content = await readFile(file, 'text');
|
|
353
|
+
console.log(content);
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
// 读取为 ArrayBuffer
|
|
357
|
+
const handleBinaryFile = async (file: File) => {
|
|
358
|
+
const buffer = await readFile(file, 'arrayBuffer');
|
|
359
|
+
console.log(buffer);
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
// 读取为 Data URL (Base64)
|
|
363
|
+
const handleDataUrl = async (file: File) => {
|
|
364
|
+
const dataUrl = await readFile(file, 'dataURL');
|
|
365
|
+
console.log(dataUrl);
|
|
366
|
+
};
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### readTxtFile(file: File | Blob, encoding?: string): Promise<string>
|
|
370
|
+
|
|
371
|
+
读取 TXT 文件,返回纯文本内容。
|
|
372
|
+
|
|
373
|
+
```ts
|
|
374
|
+
import { readTxtFile } from '@giszhc/file-utils';
|
|
375
|
+
|
|
376
|
+
const content = await readTxtFile(file);
|
|
377
|
+
console.log(content);
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### readCsvFile(file: File | Blob, options?: CsvOptions): Promise<any[]>
|
|
381
|
+
|
|
382
|
+
读取 CSV 文件,自动解析为对象数组或二维数组。
|
|
383
|
+
|
|
384
|
+
```ts
|
|
385
|
+
import { readCsvFile } from '@giszhc/file-utils';
|
|
386
|
+
|
|
387
|
+
// 读取为对象数组(假设有表头)
|
|
388
|
+
const data = await readCsvFile(file);
|
|
389
|
+
data.forEach(row => {
|
|
390
|
+
console.log(row.name, row.age);
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
// 自定义分隔符(TSV)
|
|
394
|
+
const tsvData = await readCsvFile(file, { separator: '\t' });
|
|
395
|
+
|
|
396
|
+
// 不包含表头,返回二维数组
|
|
397
|
+
const arrayData = await readCsvFile(file, { hasHeader: false });
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### readJsonFile<T>(file: File | Blob): Promise<T>
|
|
401
|
+
|
|
402
|
+
读取 JSON 文件,返回解析后的 JavaScript 对象,支持泛型类型定义。
|
|
403
|
+
|
|
404
|
+
```ts
|
|
405
|
+
import { readJsonFile } from '@giszhc/file-utils';
|
|
406
|
+
|
|
407
|
+
// 读取 JSON 配置
|
|
408
|
+
const config = await readJsonFile<{ apiEndpoint: string; version: string }>(file);
|
|
409
|
+
console.log(config.apiEndpoint);
|
|
410
|
+
|
|
411
|
+
// 读取用户数据
|
|
412
|
+
const user = await readJsonFile<{ name: string; email: string }>(file);
|
|
413
|
+
console.log(user.name);
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### downloadFile(url: string, filename?: string): Promise<void>
|
|
417
|
+
|
|
418
|
+
从 URL 下载文件。支持跨域下载(需服务器支持 CORS)。
|
|
419
|
+
|
|
420
|
+
```ts
|
|
421
|
+
import { downloadFile } from '@giszhc/file-utils';
|
|
422
|
+
|
|
423
|
+
// 下载文件并指定文件名
|
|
424
|
+
await downloadFile('https://example.com/file.pdf', 'my-file.pdf');
|
|
425
|
+
|
|
426
|
+
// 使用默认文件名
|
|
427
|
+
await downloadFile('https://example.com/image.jpg');
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### downloadBlob(blob: Blob, filename: string): void
|
|
431
|
+
|
|
432
|
+
下载 Blob 对象。
|
|
433
|
+
|
|
434
|
+
```ts
|
|
435
|
+
import { downloadBlob } from '@giszhc/file-utils';
|
|
436
|
+
|
|
437
|
+
const blob = new Blob(['Hello World'], { type: 'text/plain' });
|
|
438
|
+
downloadBlob(blob, 'hello.txt');
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### downloadBase64(base64: string, filename: string, mimeType?: string): void
|
|
442
|
+
|
|
443
|
+
下载 Base64 编码的文件。
|
|
444
|
+
|
|
445
|
+
```ts
|
|
446
|
+
import { downloadBase64 } from '@giszhc/file-utils';
|
|
447
|
+
|
|
448
|
+
const base64Data = 'data:image/png;base64,iVBORw0KGgoAAAANS...';
|
|
449
|
+
downloadBase64(base64Data, 'image.png');
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### fileToBase64(file: File | Blob): Promise<string>
|
|
453
|
+
|
|
454
|
+
将 File 或 Blob 对象转换为 Base64 编码。
|
|
455
|
+
|
|
456
|
+
```ts
|
|
457
|
+
import { fileToBase64 } from '@giszhc/file-utils';
|
|
458
|
+
|
|
459
|
+
const input = document.querySelector('input[type="file"]');
|
|
460
|
+
input.addEventListener('change', async (e) => {
|
|
461
|
+
const file = e.target.files[0];
|
|
462
|
+
const base64 = await fileToBase64(file);
|
|
463
|
+
console.log(base64);
|
|
464
|
+
});
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### base64ToBlob(base64: string, mimeType?: string): Blob
|
|
468
|
+
|
|
469
|
+
将 Base64 编码转换为 Blob 对象。
|
|
470
|
+
|
|
471
|
+
```ts
|
|
472
|
+
import { base64ToBlob } from '@giszhc/file-utils';
|
|
473
|
+
|
|
474
|
+
const base64 = 'data:image/png;base64,iVBORw0KGgoAAAANS...';
|
|
475
|
+
const blob = base64ToBlob(base64);
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### compressImage(file: File, quality?: number, maxWidth?: number, maxHeight?: number): Promise<Blob>
|
|
479
|
+
|
|
480
|
+
压缩图片文件。支持调整质量和最大尺寸。
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
import { compressImage } from '@giszhc/file-utils';
|
|
484
|
+
|
|
485
|
+
const handleImageUpload = async (file: File) => {
|
|
486
|
+
// 压缩到 80% 质量,最大宽度 1920px
|
|
487
|
+
const compressed = await compressImage(file, 0.8, 1920);
|
|
488
|
+
|
|
489
|
+
// 使用压缩后的文件上传
|
|
490
|
+
const formData = new FormData();
|
|
491
|
+
formData.append('image', compressed, file.name);
|
|
492
|
+
};
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### generateTxtFile(content: string, filename: string, encoding?: string): void
|
|
496
|
+
|
|
497
|
+
生成并下载 TXT 文件。
|
|
498
|
+
|
|
499
|
+
```ts
|
|
500
|
+
import { generateTxtFile } from '@giszhc/file-utils';
|
|
501
|
+
|
|
502
|
+
// 生成简单的文本文件
|
|
503
|
+
generateTxtFile('Hello World!', 'hello.txt');
|
|
504
|
+
|
|
505
|
+
// 生成多行文本
|
|
506
|
+
const lines = ['第一行', '第二行', '第三行'].join('\n');
|
|
507
|
+
generateTxtFile(lines, 'multiline.txt');
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### generateCsvFile(data: Record<string, any>[] | any[][], filename: string, options?: CsvOptions): void
|
|
511
|
+
|
|
512
|
+
生成并下载 CSV 文件。支持对象数组和二维数组,自动处理表头和字段转义。
|
|
513
|
+
|
|
514
|
+
```ts
|
|
515
|
+
import { generateCsvFile } from '@giszhc/file-utils';
|
|
516
|
+
|
|
517
|
+
// 使用对象数组
|
|
518
|
+
const users = [
|
|
519
|
+
{ name: '张三', age: 25, city: '北京' },
|
|
520
|
+
{ name: '李四', age: 30, city: '上海' }
|
|
521
|
+
];
|
|
522
|
+
generateCsvFile(users, 'users.csv');
|
|
523
|
+
|
|
524
|
+
// 使用二维数组
|
|
525
|
+
const data = [
|
|
526
|
+
['姓名', '年龄', '城市'],
|
|
527
|
+
['张三', 25, '北京'],
|
|
528
|
+
['李四', 30, '上海']
|
|
529
|
+
];
|
|
530
|
+
generateCsvFile(data, 'data.csv');
|
|
531
|
+
|
|
532
|
+
// 自定义配置(制表符分隔、不包含表头)
|
|
533
|
+
generateCsvFile(data, 'data.tsv', {
|
|
534
|
+
separator: '\t',
|
|
535
|
+
includeHeader: false
|
|
536
|
+
});
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### generateJsonFile(data: any, filename: string, options?: JsonOptions): void
|
|
540
|
+
|
|
541
|
+
生成并下载 JSON 文件。支持格式化和压缩输出。
|
|
542
|
+
|
|
543
|
+
```ts
|
|
544
|
+
import { generateJsonFile } from '@giszhc/file-utils';
|
|
545
|
+
|
|
546
|
+
// 生成简单的 JSON 文件
|
|
547
|
+
const data = { name: '张三', age: 25 };
|
|
548
|
+
generateJsonFile(data, 'user.json');
|
|
549
|
+
|
|
550
|
+
// 格式化输出(默认)
|
|
551
|
+
const users = [
|
|
552
|
+
{ name: '张三', age: 25 },
|
|
553
|
+
{ name: '李四', age: 30 }
|
|
554
|
+
];
|
|
555
|
+
generateJsonFile(users, 'users.json');
|
|
556
|
+
|
|
557
|
+
// 压缩输出
|
|
558
|
+
generateJsonFile(data, 'data.min.json', { pretty: false });
|
|
559
|
+
|
|
560
|
+
// 自定义缩进
|
|
561
|
+
generateJsonFile(data, 'data.json', { spaces: 4 });
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### getFileExtension(file: File | string): string
|
|
565
|
+
|
|
566
|
+
获取文件扩展名(后缀),包含点号。
|
|
567
|
+
|
|
568
|
+
```ts
|
|
569
|
+
import { getFileExtension } from '@giszhc/file-utils';
|
|
570
|
+
|
|
571
|
+
const file = new File(['content'], 'document.pdf', { type: 'application/pdf' });
|
|
572
|
+
const ext = getFileExtension(file); // ".pdf"
|
|
573
|
+
|
|
574
|
+
// 也可以传入文件名
|
|
575
|
+
const ext2 = getFileExtension('image.png'); // ".png"
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### getFileNameWithoutExtension(file: File | string): string
|
|
579
|
+
|
|
580
|
+
获取文件名(不含扩展名)。
|
|
581
|
+
|
|
582
|
+
```ts
|
|
583
|
+
import { getFileNameWithoutExtension } from '@giszhc/file-utils';
|
|
584
|
+
|
|
585
|
+
const file = new File(['content'], 'archive.tar.gz', { type: 'application/gzip' });
|
|
586
|
+
const name = getFileNameWithoutExtension(file); // "archive.tar"
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
### checkFileType(file: File, acceptTypes: string[]): boolean
|
|
590
|
+
|
|
591
|
+
检查文件类型是否匹配。支持 MIME 类型、通配符和扩展名。
|
|
592
|
+
|
|
593
|
+
```ts
|
|
594
|
+
import { checkFileType } from '@giszhc/file-utils';
|
|
595
|
+
|
|
596
|
+
// 精确匹配 MIME 类型
|
|
597
|
+
checkFileType(file, ['image/jpeg']);
|
|
598
|
+
|
|
599
|
+
// 使用通配符
|
|
600
|
+
checkFileType(file, ['image/*', 'application/pdf']);
|
|
601
|
+
|
|
602
|
+
// 使用扩展名
|
|
603
|
+
checkFileType(file, ['.jpg', '.png', '.gif']);
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
### checkFileSize(file: File, maxSize: number): boolean
|
|
607
|
+
|
|
608
|
+
检查文件大小是否符合要求(字节)。
|
|
609
|
+
|
|
610
|
+
```ts
|
|
611
|
+
import { checkFileSize } from '@giszhc/file-utils';
|
|
612
|
+
|
|
613
|
+
// 限制不超过 2MB
|
|
614
|
+
const isValid = checkFileSize(file, 2 * 1024 * 1024);
|
|
615
|
+
if (!isValid) {
|
|
616
|
+
console.log('文件过大');
|
|
617
|
+
}
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### isImage(file: File): boolean
|
|
621
|
+
|
|
622
|
+
快速判断文件是否为图片格式。
|
|
623
|
+
|
|
624
|
+
```ts
|
|
625
|
+
import { isImage } from '@giszhc/file-utils';
|
|
626
|
+
|
|
627
|
+
if (isImage(file)) {
|
|
628
|
+
console.log('这是一个图片文件');
|
|
629
|
+
}
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### getImageDimensions(file: File): Promise<{ width: number, height: number }>
|
|
633
|
+
|
|
634
|
+
异步获取图片的原始宽高。
|
|
635
|
+
|
|
636
|
+
```ts
|
|
637
|
+
import { getImageDimensions } from '@giszhc/file-utils';
|
|
638
|
+
|
|
639
|
+
const dimensions = await getImageDimensions(file);
|
|
640
|
+
console.log(`图片尺寸:${dimensions.width} x ${dimensions.height}`);
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### validateFile(file: File, options?: IFileValidationOptions): Promise<IValidationResult>
|
|
644
|
+
|
|
645
|
+
综合文件验证,在上传前进行合法性检查。
|
|
646
|
+
|
|
647
|
+
```ts
|
|
648
|
+
import { validateFile } from '@giszhc/file-utils';
|
|
649
|
+
|
|
650
|
+
const result = await validateFile(file, {
|
|
651
|
+
acceptTypes: ['image/jpeg', 'image/png'],
|
|
652
|
+
maxSize: 2 * 1024 * 1024, // 2MB
|
|
653
|
+
mustBeImage: true,
|
|
654
|
+
minWidth: 800,
|
|
655
|
+
maxWidth: 4096,
|
|
656
|
+
minHeight: 600,
|
|
657
|
+
maxHeight: 4096
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
if (!result.valid) {
|
|
661
|
+
// 显示所有错误
|
|
662
|
+
result.errors.forEach(err => console.error(err));
|
|
663
|
+
} else {
|
|
664
|
+
console.log('验证通过');
|
|
665
|
+
}
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
------
|
|
669
|
+
|
|
670
|
+
## 类型定义
|
|
671
|
+
|
|
672
|
+
```ts
|
|
673
|
+
// 文件读取类型
|
|
674
|
+
export type ReadFileType = 'text' | 'arrayBuffer' | 'dataURL' | 'binaryString';
|
|
675
|
+
|
|
676
|
+
// 压缩选项
|
|
677
|
+
export interface CompressOptions {
|
|
678
|
+
quality?: number; // 压缩质量 (0-1),默认 0.8
|
|
679
|
+
maxWidth?: number; // 最大宽度,默认无限制
|
|
680
|
+
maxHeight?: number; // 最大高度,默认无限制
|
|
681
|
+
mimeType?: string; // 输出 MIME 类型,默认 'image/jpeg'
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// 文件验证结果
|
|
685
|
+
export interface IValidationResult {
|
|
686
|
+
valid: boolean; // 是否通过验证
|
|
687
|
+
errors: string[]; // 错误信息列表
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// 文件验证选项
|
|
691
|
+
export interface IFileValidationOptions {
|
|
692
|
+
acceptTypes?: string[]; // 接受的文件类型
|
|
693
|
+
maxSize?: number; // 最大文件大小(字节)
|
|
694
|
+
mustBeImage?: boolean; // 是否必须为图片
|
|
695
|
+
minWidth?: number; // 最小宽度(图片)
|
|
696
|
+
maxWidth?: number; // 最大宽度(图片)
|
|
697
|
+
minHeight?: number; // 最小高度(图片)
|
|
698
|
+
maxHeight?: number; // 最大高度(图片)
|
|
699
|
+
}
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
------
|
|
703
|
+
|
|
704
|
+
## 注意事项
|
|
705
|
+
|
|
706
|
+
1. **内存管理**:使用 `downloadFile` 或 `downloadBlob` 等方法时,库会自动清理临时创建的 Blob URL,无需手动释放
|
|
707
|
+
2. **CORS 限制**:从 URL 下载文件时,需要目标服务器支持 CORS
|
|
708
|
+
3. **浏览器兼容性**:部分 API 可能需要较新的浏览器支持(如 ES2020+)
|
|
709
|
+
4. **文件大小限制**:读取大文件时注意浏览器内存限制
|
|
710
|
+
|