@giszhc/file-utils 0.0.4 → 0.0.6

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 CHANGED
@@ -7,15 +7,99 @@
7
7
  - **文件读取**:支持读取文本、二进制数据、Data URL 等
8
8
  - **文件下载**:支持从 URL、Blob、Base64 等多种方式下载文件
9
9
  - **文件转换**:支持文件格式转换(如 Base64 转 Blob、File 转 Base64 等)
10
+ - **文件压缩**:支持将多个文件打包为 ZIP 压缩包
10
11
  - **文件压缩**:支持图片压缩处理
11
12
  - **文件生成**:支持生成 TXT、CSV、JSON 格式文件,可选择返回 File 对象而不下载
12
13
  - **文件验证**:提供完整的文件验证和类型判断功能
13
14
  - **剪贴板操作**:支持一键复制文本到剪贴板,并支持成功/失败回调
15
+ - **辅助工具**:提供深拷贝、UUID 生成、URL 参数解析、对象转 FormData 等实用工具
16
+ - **正则验证**:提供邮箱、手机、URL、坐标等多种表单验证功能
14
17
  - **自动清理**:自动管理临时创建的 Blob URL,防止内存泄漏
15
18
  - **TypeScript**:完善的类型定义支持
16
19
 
17
20
  ------
18
21
 
22
+ ## 方法列表
23
+
24
+ ### 文件读取
25
+ - `readFile` - 读取文件内容为文本、ArrayBuffer 或 DataURL
26
+ - `readTxtFile` - 读取 TXT 文件内容
27
+ - `readCsvFile` - 读取 CSV 文件并解析为对象数组
28
+ - `readJsonFile` - 读取 JSON 文件并解析为 JavaScript 对象
29
+
30
+ ### 文件下载
31
+ - `downloadFile` - 从 URL 下载文件
32
+ - `downloadBlob` - 下载 Blob 对象
33
+ - `downloadBase64` - 下载 Base64 编码的文件
34
+ - `downloadMultiple` - 批量下载多个文件
35
+
36
+ ### 文件转换
37
+ - `fileToBase64` - 将 File/Blob 转换为 Base64
38
+ - `base64ToBlob` - 将 Base64 转换为 Blob
39
+ - `blobToFile` - 将 Blob 转换为指定文件名的 File
40
+ - `base64ToFile` - 将 Base64 转换为 File
41
+ - `imageUrlToBase64` - 将图片 URL 转换为 Base64
42
+ - `fileChangedImageDPI` - 修改图片的 DPI 分辨率
43
+ - `compressImage` - 压缩图片
44
+
45
+ ### 文件压缩
46
+ - `fileListToZip` - 将文件列表打包为 ZIP
47
+ - `downloadFileListAsZip` - 下载文件列表的 ZIP 压缩包
48
+
49
+ ### 文件生成
50
+ - `generateTxtFile` - 生成 TXT 文件
51
+ - `generateCsvFile` - 生成 CSV 文件
52
+ - `generateJsonFile` - 生成 JSON 文件
53
+
54
+ ### 文件验证
55
+ - `checkFileType` - 检查文件类型
56
+ - `checkFileSize` - 检查文件大小
57
+ - `isImage` - 判断是否为图片
58
+ - `getImageDimensions` - 获取图片尺寸
59
+ - `validateFile` - 综合文件验证
60
+ - `formatFileSize` - 格式化文件大小显示
61
+ - `getFileNameSuffix` - 获取文件扩展名(不含点号)
62
+ - `getFileNamePrefix` - 获取文件名(不含扩展名)
63
+ - `getFileInfo` - 获取文件完整信息
64
+
65
+ ### 剪贴板操作
66
+ - `copyToClipboard` - 复制文本到剪贴板
67
+ - `pasteFromClipboard` - 从剪贴板读取文本
68
+
69
+ ### 辅助工具
70
+ - `deepClone` - 深拷贝对象和数组
71
+ - `numberFixed` - 数字保留指定小数位
72
+ - `parseUrlParams` - 解析 URL 参数为对象
73
+ - `objectToFormData` - 对象转换为 FormData
74
+ - `omitKeys` - 从对象中移除指定的键
75
+ - `generateUUID` - 生成 UUID(支持移除横杠)
76
+ - `arraySum` - 数字数组求和
77
+ - `formatAmount` - 格式化金额(千分位)
78
+ - `maskString` - 字符串中间部分替换为星号
79
+ - `formatPhone` - 格式化手机号码(隐藏中间 4 位)
80
+ - `arrayStringFormatNumber` - 字符串数组转数值数组
81
+ - `arrayCustomSort` - 自定义排序(按指定 id 顺序)
82
+ - `jsonConvertTreeList` - 扁平数据转树形结构
83
+ - `jsonConvertGeneralList` - 树形结构转扁平数据
84
+
85
+ ### 正则验证 (VerifyUtils)
86
+ - `VerifyUtils.isEmail` - 邮箱验证
87
+ - `VerifyUtils.isNumber` - 数字验证
88
+ - `VerifyUtils.isPhone` - 手机号验证
89
+ - `VerifyUtils.isUrl` - URL 链接验证
90
+ - `VerifyUtils.isIP` - IP 地址验证
91
+ - `VerifyUtils.isNoSpace` - 无空格验证
92
+ - `VerifyUtils.isChinese` - 中文验证
93
+ - `VerifyUtils.isPassword` - 密码强度验证
94
+ - `VerifyUtils.isLongitude` - 经度验证
95
+ - `VerifyUtils.isLatitude` - 纬度验证
96
+ - `VerifyUtils.isInputCoordinates` - 坐标串验证
97
+ - `VerifyUtils.isEmpty` - 空值检查
98
+ - `VerifyUtils.getRule` - 生成表单验证规则
99
+ - `VerifyUtils.validate` - 带错误消息的验证
100
+
101
+ ------
102
+
19
103
  ## 安装
20
104
 
21
105
  你可以通过 npm 安装该库:
@@ -239,15 +323,15 @@ console.log(file.size); // 文件大小(字节)
239
323
  ### 11. 获取文件扩展名和文件名
240
324
 
241
325
  ```ts
242
- import { getFileExtension, getFileNameWithoutExtension } from '@giszhc/file-utils';
326
+ import { getFileNameSuffix, getFileNamePrefix } from '@giszhc/file-utils';
243
327
 
244
328
  const file = new File(['content'], 'document.pdf', { type: 'application/pdf' });
245
329
 
246
- // 获取扩展名
247
- const ext = getFileExtension(file); // ".pdf"
330
+ // 获取扩展名(不含点号)
331
+ const ext = getFileNameSuffix(file); // "pdf"
248
332
 
249
333
  // 获取文件名(不含扩展名)
250
- const name = getFileNameWithoutExtension(file); // "document"
334
+ const name = getFileNamePrefix(file); // "document"
251
335
  ```
252
336
 
253
337
  ### 12. 文件类型验证
@@ -380,6 +464,161 @@ const text = await pasteFromClipboard();
380
464
  console.log('剪贴板内容:', text);
381
465
  ```
382
466
 
467
+ ### 21. 深拷贝对象
468
+
469
+ ```ts
470
+ import { deepClone } from '@giszhc/file-utils';
471
+
472
+ // 深拷贝对象
473
+ const obj = { a: 1, b: { c: 2 }, d: [1, 2, 3] };
474
+ const copy = deepClone(obj);
475
+ copy.b.c = 3;
476
+ console.log(obj.b.c); // 2 (原对象不受影响)
477
+
478
+ // 支持 Date、RegExp 等特殊类型
479
+ const data = {
480
+ date: new Date(),
481
+ regex: /test/g,
482
+ nested: { array: [1, 2, 3] }
483
+ };
484
+ const cloned = deepClone(data);
485
+ ```
486
+
487
+ ### 22. 数字保留小数位
488
+
489
+ ```ts
490
+ import { numberFixed } from '@giszhc/file-utils';
491
+
492
+ // 保留 2 位小数(默认)
493
+ const num1 = numberFixed(3.14159); // 3.14
494
+
495
+ // 自定义小数位数
496
+ const num2 = numberFixed(10, 3); // 10
497
+ const num3 = numberFixed(2.5678, 1); // 2.6
498
+ ```
499
+
500
+ ### 23. 解析 URL 参数
501
+
502
+ ```ts
503
+ import { parseUrlParams } from '@giszhc/file-utils';
504
+
505
+ // 解析当前页面 URL 参数
506
+ const params = parseUrlParams();
507
+ console.log(params.id); // 从当前 URL 获取 id 参数
508
+
509
+ // 解析指定 URL 参数
510
+ const url = 'https://example.com?name=John&age=30';
511
+ const urlParams = parseUrlParams(url);
512
+ // { name: 'John', age: '30' }
513
+ ```
514
+
515
+ ### 24. 对象转 FormData
516
+
517
+ ```ts
518
+ import { objectToFormData } from '@giszhc/file-utils';
519
+
520
+ // 简单对象转换
521
+ const obj = { name: 'John', age: 30 };
522
+ const formData = objectToFormData(obj);
523
+
524
+ // 嵌套对象
525
+ const user = {
526
+ name: 'John',
527
+ profile: {
528
+ email: 'john@example.com',
529
+ phone: '123456'
530
+ }
531
+ };
532
+ const fd = objectToFormData(user);
533
+
534
+ // 包含文件
535
+ const fileInput = document.querySelector('input[type="file"]');
536
+ const data = {
537
+ avatar: fileInput.files[0],
538
+ description: 'User avatar'
539
+ };
540
+ const fdWithFile = objectToFormData(data);
541
+ ```
542
+
543
+ ### 25. 移除对象的特定键
544
+
545
+ ```ts
546
+ import { omitKeys } from '@giszhc/file-utils';
547
+
548
+ // 移除指定的键
549
+ const obj = { a: 1, b: 2, c: 3, d: 4 };
550
+ const result = omitKeys(obj, ['b', 'd']);
551
+ // { a: 1, c: 3 }
552
+
553
+ // 反向操作:只保留指定的键
554
+ const filtered = omitKeys(obj, ['a', 'c'], true);
555
+ // { a: 1, c: 3 }
556
+ ```
557
+
558
+ ### 26. 生成 UUID
559
+
560
+ ```ts
561
+ import { generateUUID } from '@giszhc/file-utils';
562
+
563
+ // 生成带横杠的 UUID(默认)
564
+ const uuid1 = generateUUID();
565
+ // "550e8400-e29b-41d4-a716-446655440000"
566
+
567
+ // 生成不带横杠的 UUID
568
+ const uuid2 = generateUUID(true);
569
+ // "550e8400e29b41d4a716446655440000"
570
+
571
+ // 使用场景:生成唯一 ID
572
+ const userId = generateUUID();
573
+ const requestId = generateUUID(true); // 无横杠版本用于数据库存储
574
+ ```
575
+
576
+ ### 27. 正则验证工具类
577
+
578
+ ```ts
579
+ import { VerifyUtils } from '@giszhc/file-utils';
580
+
581
+ // 基础验证
582
+ VerifyUtils.isEmail('test@example.com'); // true
583
+ VerifyUtils.isPhone('13800138000'); // true
584
+ VerifyUtils.isUrl('https://example.com'); // true
585
+ VerifyUtils.isNumber('123.45'); // true
586
+ VerifyUtils.isNoSpace('hello'); // true
587
+ VerifyUtils.isChinese('你好'); // true
588
+ VerifyUtils.isPassword('Abc@1234'); // true
589
+
590
+ // 经纬度验证
591
+ VerifyUtils.isLongitude(116.4); // true
592
+ VerifyUtils.isLatitude(39.9); // true
593
+
594
+ // 坐标串验证(支持多级分隔符)
595
+ VerifyUtils.isInputCoordinates('116.4,39.9'); // true
596
+ VerifyUtils.isInputCoordinates('116.4,39.9;117.4,40.9'); // true
597
+ VerifyUtils.isInputCoordinates('116.4,39.9|117.4,40.9'); // true
598
+
599
+ // 空值检查
600
+ VerifyUtils.isEmpty(''); // true
601
+ VerifyUtils.isEmpty(null); // true
602
+ VerifyUtils.isEmpty([]); // true
603
+ VerifyUtils.isEmpty({}); // true
604
+
605
+ // 生成 Element UI 表单验证规则
606
+ const rules = {
607
+ email: [
608
+ { required: true, message: '请输入邮箱', trigger: 'blur' },
609
+ VerifyUtils.getRule('email', 'blur')
610
+ ],
611
+ phone: [
612
+ { required: true, message: '请输入手机号', trigger: 'blur' },
613
+ VerifyUtils.getRule('phone', 'blur')
614
+ ],
615
+ url: [VerifyUtils.getRule('url')]
616
+ };
617
+
618
+ // 获取错误提示语
619
+ console.log(VerifyUtils.messages.email); // "请输入正确的邮箱地址"
620
+ ```
621
+
383
622
  ------
384
623
 
385
624
  ## 使用方法
@@ -519,6 +758,92 @@ const base64 = 'data:image/png;base64,iVBORw0KGgoAAAANS...';
519
758
  const blob = base64ToBlob(base64);
520
759
  ```
521
760
 
761
+ ### base64ToFile(base64: string, filename?: string, mimeType?: string): File
762
+
763
+ 将 Base64 编码转换为 File 对象。
764
+
765
+ ```ts
766
+ import { base64ToFile } from '@giszhc/file-utils';
767
+
768
+ // 转换带前缀的 Base64
769
+ const base64 = 'data:image/png;base64,iVBORw0KGgoAAAANS...';
770
+ const file = base64ToFile(base64, 'image.png');
771
+ console.log(file.name); // "image.png"
772
+
773
+ // 转换不带前缀的 Base64
774
+ const pureBase64 = 'iVBORw0KGgoAAAANS...';
775
+ const file2 = base64ToFile(pureBase64, 'image.png', 'image/png');
776
+ ```
777
+
778
+ ### imageUrlToBase64(imageUrl: string, mimeType?: string, quality?: number): Promise<string>
779
+
780
+ 将图片 URL 转换为 Base64 编码。使用 Canvas 将图片绘制后转换为 Base64。
781
+
782
+ ```ts
783
+ import { imageUrlToBase64 } from '@giszhc/file-utils';
784
+
785
+ // 转换远程图片
786
+ const base64 = await imageUrlToBase64('https://example.com/image.jpg');
787
+ console.log(base64); // data:image/png;base64,...
788
+
789
+ // 转换为 JPEG 格式,80% 质量
790
+ const jpegBase64 = await imageUrlToBase64(
791
+ 'https://example.com/image.png',
792
+ 'image/jpeg',
793
+ 0.8
794
+ );
795
+ ```
796
+
797
+ ### fileChangedImageDPI(source: string | Blob, dpi?: number): Promise<string | Blob>
798
+
799
+ 修改图片的分辨率 DPI(每英寸点数)。支持 Base64 字符串和 Blob 对象。返回 Promise。
800
+
801
+ ```ts
802
+ import { fileChangedImageDPI } from '@giszhc/file-utils';
803
+
804
+ // 修改 Base64 图片的 DPI 为 300(适合打印)
805
+ const base64 = 'data:image/png;base64,iVBORw0KGgoAAAANS...';
806
+ const highDpiBase64 = await fileChangedImageDPI(base64, 300);
807
+ console.log('高分辨率图片:', highDpiBase64);
808
+
809
+ // 修改 Blob 图片的 DPI
810
+ const blob = new Blob([imageData], { type: 'image/png' });
811
+ const newBlob = await fileChangedImageDPI(blob, 300);
812
+ // newBlob 是修改后的 Blob 对象
813
+
814
+ // 使用默认 DPI (96,屏幕显示标准)
815
+ const defaultDpiResult = await fileChangedImageDPI(base64);
816
+
817
+ // 设置为 72 DPI(网页优化)
818
+ const webOptimized = await fileChangedImageDPI(base64, 72);
819
+
820
+ // 结合其他方法使用
821
+ import { fileToBase64, base64ToBlob, fileChangedImageDPI } from '@giszhc/file-utils';
822
+
823
+ const handleImageUpload = async (file: File) => {
824
+ // 方式 1: 使用 Base64
825
+ const base64 = await fileToBase64(file);
826
+ const highResBase64 = await fileChangedImageDPI(base64, 300);
827
+
828
+ // 方式 2: 直接使用 Blob
829
+ const highResBlob = await fileChangedImageDPI(file, 300);
830
+ const highResFile = base64ToFile(highResBase64, 'high-res.png');
831
+ };
832
+ ```
833
+
834
+ **应用场景:**
835
+ - 🖼️ **打印前提升 DPI**:将网络图片的 DPI 从 72 提升到 300,获得更好的打印质量
836
+ - 🌐 **网页优化**:降低 DPI 到 72,减少文件体积,加快网页加载速度
837
+ - 📱 **设备适配**:根据不同设备的显示需求调整 DPI
838
+ - 📄 **出版印刷**:满足专业印刷的 300 DPI 或更高要求
839
+
840
+ **注意事项:**
841
+ - 该方法仅修改图片元数据中的 DPI 值,不会改变图片的像素尺寸
842
+ - DPI 值越高,打印时的物理尺寸越小,但细节越清晰
843
+ - 标准屏幕显示通常使用 96 DPI,印刷品通常需要 300 DPI
844
+ - 输入类型为 Base64 时返回 Base64,输入类型为 Blob 时返回 Blob
845
+ - **该方法是异步函数,需要使用 await 调用**
846
+
522
847
  ### compressImage(file: File, quality?: number, maxWidth?: number, maxHeight?: number): Promise<Blob>
523
848
 
524
849
  压缩图片文件。支持调整质量和最大尺寸。
@@ -709,6 +1034,160 @@ if (!result.valid) {
709
1034
  }
710
1035
  ```
711
1036
 
1037
+ ### arrayStringFormatNumber(arrayList: string[]): number[]
1038
+
1039
+ 将字符串数组转换为数值数组。
1040
+
1041
+ ```ts
1042
+ import { arrayStringFormatNumber } from '@giszhc/file-utils';
1043
+
1044
+ // 将字符串数字数组转换为数值数组
1045
+ const strArr = ["0", "1", "2", "3", "4"];
1046
+ const numArr = arrayStringFormatNumber(strArr);
1047
+ console.log(numArr); // [0, 1, 2, 3, 4]
1048
+
1049
+ // 处理带小数点的字符串
1050
+ const decimalStrs = ["1.5", "2.7", "3.14"];
1051
+ const decimalNums = arrayStringFormatNumber(decimalStrs);
1052
+ console.log(decimalNums); // [1.5, 2.7, 3.14]
1053
+ ```
1054
+
1055
+ ### arrayCustomSort(ids: string[], dataList: any[], cbA: Function, cbB: Function): void
1056
+
1057
+ 根据给定的 id 顺序对数据列表进行排序。
1058
+
1059
+ ```ts
1060
+ import { arrayCustomSort } from '@giszhc/file-utils';
1061
+
1062
+ // 基本使用
1063
+ const ids = ['id1', 'id2', 'id3'];
1064
+ const dataList = [
1065
+ { id: 'id3', name: 'Layer 3' },
1066
+ { id: 'id1', name: 'Layer 1' },
1067
+ { id: 'id2', name: 'Layer 2' }
1068
+ ];
1069
+
1070
+ arrayCustomSort(ids, dataList, item => item.id, item => item.id);
1071
+ // 排序后:[
1072
+ // { id: 'id1', name: 'Layer 1' },
1073
+ // { id: 'id2', name: 'Layer 2' },
1074
+ // { id: 'id3', name: 'Layer 3' }
1075
+ // ]
1076
+
1077
+ // 使用不同的回调函数处理不同类型的数据
1078
+ const orderIds = ['admin', 'user', 'guest'];
1079
+ const roles = [
1080
+ { roleId: 'guest', roleName: '访客' },
1081
+ { roleId: 'admin', roleName: '管理员' },
1082
+ { roleId: 'user', roleName: '普通用户' }
1083
+ ];
1084
+
1085
+ arrayCustomSort(orderIds, roles, role => role.roleId, role => role.roleId);
1086
+ // 按指定顺序排序:管理员、普通用户、访客
1087
+ ```
1088
+
1089
+ ### jsonConvertTreeList(dataList: any[]): any[]
1090
+
1091
+ 将扁平数据数组转换为树形结构。
1092
+
1093
+ ```ts
1094
+ import { jsonConvertTreeList } from '@giszhc/file-utils';
1095
+
1096
+ // 扁平数据
1097
+ const flatData = [
1098
+ { id: 1, pid: null, name: '根节点' },
1099
+ { id: 2, pid: 1, name: '子节点 1' },
1100
+ { id: 3, pid: 1, name: '子节点 2' },
1101
+ { id: 4, pid: 2, name: '孙节点 1' }
1102
+ ];
1103
+
1104
+ const tree = jsonConvertTreeList(flatData);
1105
+ /*
1106
+ 返回树形结构:
1107
+ [
1108
+ {
1109
+ id: 1,
1110
+ pid: null,
1111
+ name: '根节点',
1112
+ children: [
1113
+ {
1114
+ id: 2,
1115
+ pid: 1,
1116
+ name: '子节点 1',
1117
+ children: [
1118
+ { id: 4, pid: 2, name: '孙节点 1' }
1119
+ ]
1120
+ },
1121
+ {
1122
+ id: 3,
1123
+ pid: 1,
1124
+ name: '子节点 2',
1125
+ children: []
1126
+ }
1127
+ ]
1128
+ }
1129
+ ]
1130
+ */
1131
+
1132
+ // 应用场景:菜单生成、组织架构展示
1133
+ const menuData = [
1134
+ { id: 1, pid: null, title: '系统管理' },
1135
+ { id: 2, pid: 1, title: '用户管理' },
1136
+ { id: 3, pid: 1, title: '角色管理' },
1137
+ { id: 4, pid: 2, title: '用户列表' },
1138
+ { id: 5, pid: 2, title: '用户新增' }
1139
+ ];
1140
+
1141
+ const menuTree = jsonConvertTreeList(menuData);
1142
+ ```
1143
+
1144
+ ### jsonConvertGeneralList(treeList: any[], delChildrenField?: boolean): any[]
1145
+
1146
+ 将树形结构转换回扁平数据数组。
1147
+
1148
+ ```ts
1149
+ import { jsonConvertGeneralList } from '@giszhc/file-utils';
1150
+
1151
+ // 树形结构
1152
+ const tree = [
1153
+ {
1154
+ id: 1,
1155
+ pid: null,
1156
+ name: '根节点',
1157
+ children: [
1158
+ {
1159
+ id: 2,
1160
+ pid: 1,
1161
+ name: '子节点 1',
1162
+ children: [
1163
+ { id: 4, pid: 2, name: '孙节点 1' }
1164
+ ]
1165
+ },
1166
+ {
1167
+ id: 3,
1168
+ pid: 1,
1169
+ name: '子节点 2',
1170
+ children: []
1171
+ }
1172
+ ]
1173
+ }
1174
+ ];
1175
+
1176
+ // 保留 children 字段
1177
+ const flatWithChildren = jsonConvertGeneralList(tree);
1178
+ console.log(flatWithChildren.length); // 4
1179
+
1180
+ // 删除 children 字段
1181
+ const flatWithoutChildren = jsonConvertGeneralList(tree, true);
1182
+ console.log(flatWithoutChildren[0]);
1183
+ // { id: 1, pid: null, name: '根节点' } (不含 children)
1184
+
1185
+ // 应用场景:将树形菜单保存为扁平数据存储到数据库
1186
+ const menuTree = [...]; // 树形菜单
1187
+ const flatMenuData = jsonConvertGeneralList(menuTree, true);
1188
+ // 可以发送到后端保存到数据库
1189
+ ```
1190
+
712
1191
  ------
713
1192
 
714
1193
  ## 类型定义