cloud-web-corejs 1.0.54-dev.552 → 1.0.54-dev.554
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/package.json +1 -1
- package/src/components/luckysheet/README.md +93 -21
- package/src/components/luckysheet/colorTest.js +54 -0
- package/src/components/luckysheet/dialog.vue +37 -26
- package/src/components/luckysheet/export.js +46 -14
- package/src/components/luckysheet/fileConversionExample.js +127 -0
- package/src/components/luckysheet/fileUtils.js +147 -0
- package/src/components/luckysheet/view.vue +2 -2
package/package.json
CHANGED
|
@@ -2,32 +2,104 @@
|
|
|
2
2
|
|
|
3
3
|
## 主要改进内容
|
|
4
4
|
|
|
5
|
-
### 1.
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
5
|
+
### 1. **列宽处理优化**
|
|
6
|
+
- 添加了 `setColumnWidths` 函数,能够根据原始数据的列宽配置自动设置Excel列宽
|
|
7
|
+
- 提供了合理的默认列宽(15个字符宽度)
|
|
8
|
+
- 设置了列宽范围限制(8-100个字符),避免显示异常
|
|
9
9
|
|
|
10
|
-
### 2.
|
|
11
|
-
-
|
|
10
|
+
### 2. **样式处理增强**
|
|
11
|
+
- **字体映射优化**: 改进了中文字体到Excel字体的标准映射
|
|
12
12
|
- 微软雅黑 → Microsoft YaHei
|
|
13
|
-
- 宋体 → SimSun
|
|
13
|
+
- 宋体 → SimSun
|
|
14
14
|
- 黑体 → SimHei
|
|
15
15
|
- 楷体 → KaiTi
|
|
16
16
|
- 仿宋 → FangSong
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
### 3.
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
### 4.
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
17
|
+
- **颜色处理**: 完善了RGBA颜色格式支持,正确处理透明度
|
|
18
|
+
- **字体大小**: 添加了8-72pt的范围限制
|
|
19
|
+
- **数字格式**: 新增完整的数字格式转换支持
|
|
20
|
+
|
|
21
|
+
### 3. **工作表属性完善**
|
|
22
|
+
- 添加了工作簿元数据(创建者、修改时间等)
|
|
23
|
+
- 设置了工作表属性(默认行高、标签颜色)
|
|
24
|
+
- 配置了页面设置(A4纸张、纵向布局)
|
|
25
|
+
- 使用了标准的Excel MIME类型
|
|
26
|
+
|
|
27
|
+
### 4. **新增功能**
|
|
28
|
+
- `setRowHeights`: 行高设置功能
|
|
29
|
+
- `convertNumberFormat`: 数字格式转换
|
|
30
|
+
- 更好的错误处理机制
|
|
31
|
+
- 内存管理优化
|
|
32
|
+
|
|
33
|
+
### 5. **Base64文件转换功能** ⭐ **新增**
|
|
34
|
+
- **File转Base64**: `fileToBase64(file)` - 将File对象转换为Base64数据URL
|
|
35
|
+
- **Base64转File**: `base64ToFile(base64, filename, mimeType)` - 将Base64数据转换回File对象
|
|
36
|
+
- **Base64转Blob**: `base64ToBlob(base64, mimeType)` - 将Base64数据转换为Blob对象
|
|
37
|
+
- **直接下载**: `downloadBase64File(base64, filename, mimeType)` - 直接下载Base64数据为文件
|
|
38
|
+
- **MIME类型常量**: 提供常用的文件MIME类型映射
|
|
39
|
+
|
|
40
|
+
### 6. **API接口保持兼容**
|
|
41
|
+
- 保留了原有的三个主要导出函数
|
|
42
|
+
- 添加了使用示例和详细文档
|
|
43
|
+
- 提供了多种使用场景的支持
|
|
44
|
+
|
|
45
|
+
## Base64转换功能使用说明
|
|
46
|
+
|
|
47
|
+
### 基本用法
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
import {
|
|
51
|
+
fileToBase64,
|
|
52
|
+
base64ToFile,
|
|
53
|
+
base64ToBlob,
|
|
54
|
+
downloadBase64File,
|
|
55
|
+
MIME_TYPES
|
|
56
|
+
} from './fileUtils.js';
|
|
57
|
+
|
|
58
|
+
// File转Base64
|
|
59
|
+
const base64 = await fileToBase64(file);
|
|
60
|
+
|
|
61
|
+
// Base64转File
|
|
62
|
+
const file = base64ToFile(base64, 'filename.xlsx', MIME_TYPES.EXCEL);
|
|
63
|
+
|
|
64
|
+
// Base64转Blob
|
|
65
|
+
const blob = base64ToBlob(base64, MIME_TYPES.EXCEL);
|
|
66
|
+
|
|
67
|
+
// 直接下载
|
|
68
|
+
downloadBase64File(base64, 'download.xlsx', MIME_TYPES.EXCEL);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 在对话框中的应用
|
|
72
|
+
|
|
73
|
+
对话框组件现在会在提交时自动进行双向转换:
|
|
74
|
+
- 原始File对象 → Base64字符串
|
|
75
|
+
- Base64字符串 → 转换后的File对象
|
|
76
|
+
- 返回的数据包含:`file`、`base64`、`convertedFile` 三个版本
|
|
77
|
+
|
|
78
|
+
### 支持的文件类型
|
|
79
|
+
|
|
80
|
+
```javascript
|
|
81
|
+
const MIME_TYPES = {
|
|
82
|
+
EXCEL: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
83
|
+
PDF: 'application/pdf',
|
|
84
|
+
WORD: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
85
|
+
IMAGE_JPEG: 'image/jpeg',
|
|
86
|
+
IMAGE_PNG: 'image/png',
|
|
87
|
+
IMAGE_GIF: 'image/gif',
|
|
88
|
+
TEXT: 'text/plain',
|
|
89
|
+
JSON: 'application/json'
|
|
90
|
+
};
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 使用示例
|
|
94
|
+
|
|
95
|
+
详细使用示例请参考 [fileConversionExample.js](./fileConversionExample.js) 文件。
|
|
96
|
+
|
|
97
|
+
## 注意事项
|
|
98
|
+
|
|
99
|
+
1. Base64转换会增加约33%的数据大小
|
|
100
|
+
2. 大文件转换时注意内存使用
|
|
101
|
+
3. 转换过程中会进行错误处理,失败时返回null
|
|
102
|
+
4. 文件名和MIME类型参数可以根据实际需求自定义
|
|
31
103
|
|
|
32
104
|
## API 接口说明
|
|
33
105
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { exportExcel } from './export.js'
|
|
2
|
+
|
|
3
|
+
// 测试数据 - 包含rgb()格式的颜色
|
|
4
|
+
const testData = [{
|
|
5
|
+
name: '颜色测试工作表',
|
|
6
|
+
data: [
|
|
7
|
+
// 测试rgb()背景色
|
|
8
|
+
[{
|
|
9
|
+
v: '正确的候选人',
|
|
10
|
+
bg: 'rgb(106, 168, 79)', // 绿色背景
|
|
11
|
+
fc: 'rgb(0, 0, 0)', // 黑色字体
|
|
12
|
+
bl: 1,
|
|
13
|
+
ff: 5,
|
|
14
|
+
fs: 11
|
|
15
|
+
}],
|
|
16
|
+
// 测试rgb()背景色
|
|
17
|
+
[{
|
|
18
|
+
v: '当前的候选人',
|
|
19
|
+
bg: 'rgb(255, 255, 0)', // 黄色背景
|
|
20
|
+
fc: 'rgb(0, 0, 0)', // 黑色字体
|
|
21
|
+
bl: 1,
|
|
22
|
+
ff: 5,
|
|
23
|
+
fs: 11
|
|
24
|
+
}],
|
|
25
|
+
// 测试十六进制颜色
|
|
26
|
+
[{
|
|
27
|
+
v: '十六进制测试',
|
|
28
|
+
bg: '#ff9900', // 橙色背景
|
|
29
|
+
fc: '#ffffff', // 白色字体
|
|
30
|
+
bl: 1,
|
|
31
|
+
ff: 5,
|
|
32
|
+
fs: 11
|
|
33
|
+
}]
|
|
34
|
+
],
|
|
35
|
+
config: {
|
|
36
|
+
columnlen: {0: 200},
|
|
37
|
+
rowlen: {0: 25, 1: 25, 2: 25}
|
|
38
|
+
}
|
|
39
|
+
}]
|
|
40
|
+
|
|
41
|
+
// 测试函数
|
|
42
|
+
export async function testColorExport() {
|
|
43
|
+
try {
|
|
44
|
+
console.log('开始测试颜色导出...')
|
|
45
|
+
await exportExcel(testData, 'color-test')
|
|
46
|
+
console.log('颜色测试导出完成!')
|
|
47
|
+
return true
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error('颜色测试导出失败:', error)
|
|
50
|
+
return false
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default { testColorExport }
|
|
@@ -27,12 +27,18 @@
|
|
|
27
27
|
<i class="el-icon-check el-icon"></i>
|
|
28
28
|
{{ $t2("确 定", "system.button.confirm2") }}
|
|
29
29
|
</el-button>
|
|
30
|
+
<!-- <el-button type="primary" @click="testBase64Download" class="button-sty">
|
|
31
|
+
<i class="el-icon-check el-icon"></i>
|
|
32
|
+
{{ $t1("测试base64下载") }}
|
|
33
|
+
</el-button> -->
|
|
30
34
|
</span>
|
|
31
35
|
</el-dialog>
|
|
32
36
|
</template>
|
|
33
37
|
|
|
34
38
|
<script>
|
|
35
39
|
import luckysheet from "./view.vue";
|
|
40
|
+
import { fileToBase64, base64ToFile } from "./fileUtils.js";
|
|
41
|
+
import { saveAs } from "file-saver";
|
|
36
42
|
|
|
37
43
|
export default {
|
|
38
44
|
name: "luckysheetDialog",
|
|
@@ -84,39 +90,44 @@ export default {
|
|
|
84
90
|
let luckysheetRef = this.$refs.luckysheet;
|
|
85
91
|
let value = luckysheetRef.getValue();
|
|
86
92
|
luckysheetRef.generateExcelFile((file) => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
let
|
|
97
|
-
if (
|
|
93
|
+
fileToBase64(file)
|
|
94
|
+
.then((base64) => {
|
|
95
|
+
let response = {
|
|
96
|
+
data: JSON.stringify(value),
|
|
97
|
+
json: value,
|
|
98
|
+
file: file,
|
|
99
|
+
base64: base64,
|
|
100
|
+
// convertedFile: convertedFile // 添加转换后的file对象
|
|
101
|
+
};
|
|
102
|
+
let onConfirm = this.options.onConfirm;
|
|
103
|
+
if (onConfirm && typeof onConfirm === "function") {
|
|
104
|
+
let result = onConfirm(response, this.close);
|
|
105
|
+
if (result !== false) {
|
|
106
|
+
this.close();
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
98
109
|
this.close();
|
|
99
110
|
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
111
|
+
})
|
|
112
|
+
.catch((error) => {
|
|
113
|
+
console.error("文件转换失败:", error);
|
|
114
|
+
this.$message.error("文件处理失败");
|
|
115
|
+
});
|
|
104
116
|
});
|
|
105
117
|
},
|
|
106
118
|
/**
|
|
107
|
-
*
|
|
108
|
-
* @param {File} file
|
|
109
|
-
* @returns
|
|
119
|
+
* 保留原有的fileToBase64Async方法以保持向后兼容
|
|
110
120
|
*/
|
|
111
121
|
fileToBase64Async(file) {
|
|
112
|
-
return
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
122
|
+
return fileToBase64(file);
|
|
123
|
+
} /* ,
|
|
124
|
+
testBase64Download() {
|
|
125
|
+
let base64 = this.options.base64;
|
|
126
|
+
const fileName = `电子表格_${new Date().getTime()}.xlsx`;
|
|
127
|
+
const convertedFile = base64ToFile(base64, fileName);
|
|
128
|
+
|
|
129
|
+
saveAs(convertedFile, fileName);
|
|
130
|
+
}, */,
|
|
120
131
|
},
|
|
121
132
|
};
|
|
122
133
|
</script>
|
|
@@ -312,22 +312,39 @@ var fillConvert = function(bg) {
|
|
|
312
312
|
return {}
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
-
//
|
|
316
|
-
let bgColor = bg
|
|
315
|
+
// 处理不同的颜色格式
|
|
316
|
+
let bgColor = bg;
|
|
317
|
+
|
|
318
|
+
// 处理rgb()格式的颜色
|
|
319
|
+
if (bg.startsWith('rgb(')) {
|
|
320
|
+
const rgbMatch = bg.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
321
|
+
if (rgbMatch) {
|
|
322
|
+
const r = parseInt(rgbMatch[1]).toString(16).padStart(2, '0');
|
|
323
|
+
const g = parseInt(rgbMatch[2]).toString(16).padStart(2, '0');
|
|
324
|
+
const b = parseInt(rgbMatch[3]).toString(16).padStart(2, '0');
|
|
325
|
+
bgColor = `#${r}${g}${b}`;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// 处理十六进制颜色格式
|
|
330
|
+
bgColor = bgColor.replace('#', '');
|
|
317
331
|
if (bgColor.length === 8) {
|
|
318
332
|
// 包含alpha通道,转换为ARGB
|
|
319
|
-
const alpha = bgColor.substring(0, 2)
|
|
320
|
-
const rgb = bgColor.substring(2)
|
|
321
|
-
bgColor = alpha + rgb
|
|
333
|
+
const alpha = bgColor.substring(0, 2);
|
|
334
|
+
const rgb = bgColor.substring(2);
|
|
335
|
+
bgColor = alpha + rgb;
|
|
322
336
|
} else if (bgColor.length === 6) {
|
|
323
337
|
// RGB格式,添加不透明的alpha通道
|
|
324
|
-
bgColor = 'FF' + bgColor
|
|
338
|
+
bgColor = 'FF' + bgColor;
|
|
339
|
+
} else if (bgColor.length === 3) {
|
|
340
|
+
// 简写格式 #RGB -> #RRGGBB
|
|
341
|
+
bgColor = 'FF' + bgColor.split('').map(c => c + c).join('');
|
|
325
342
|
}
|
|
326
343
|
|
|
327
344
|
let fill = {
|
|
328
345
|
type: 'pattern',
|
|
329
346
|
pattern: 'solid',
|
|
330
|
-
fgColor: { argb: bgColor }
|
|
347
|
+
fgColor: { argb: bgColor.toUpperCase() }
|
|
331
348
|
}
|
|
332
349
|
return fill
|
|
333
350
|
}
|
|
@@ -361,23 +378,38 @@ var fontConvert = function(
|
|
|
361
378
|
}
|
|
362
379
|
}
|
|
363
380
|
|
|
364
|
-
//
|
|
365
|
-
let fontColor = fc
|
|
381
|
+
// 处理字体颜色,支持rgb()格式
|
|
382
|
+
let fontColor = fc || '#000000';
|
|
383
|
+
if (fontColor.startsWith('rgb(')) {
|
|
384
|
+
const rgbMatch = fontColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
385
|
+
if (rgbMatch) {
|
|
386
|
+
const r = parseInt(rgbMatch[1]).toString(16).padStart(2, '0');
|
|
387
|
+
const g = parseInt(rgbMatch[2]).toString(16).padStart(2, '0');
|
|
388
|
+
const b = parseInt(rgbMatch[3]).toString(16).padStart(2, '0');
|
|
389
|
+
fontColor = `#${r}${g}${b}`;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// 处理十六进制颜色格式
|
|
394
|
+
fontColor = fontColor.replace('#', '');
|
|
366
395
|
if (fontColor.length === 8) {
|
|
367
396
|
// 包含alpha通道
|
|
368
|
-
const alpha = fontColor.substring(0, 2)
|
|
369
|
-
const rgb = fontColor.substring(2)
|
|
370
|
-
fontColor = alpha + rgb
|
|
397
|
+
const alpha = fontColor.substring(0, 2);
|
|
398
|
+
const rgb = fontColor.substring(2);
|
|
399
|
+
fontColor = alpha + rgb;
|
|
371
400
|
} else if (fontColor.length === 6) {
|
|
372
401
|
// RGB格式
|
|
373
|
-
fontColor = 'FF' + fontColor
|
|
402
|
+
fontColor = 'FF' + fontColor;
|
|
403
|
+
} else if (fontColor.length === 3) {
|
|
404
|
+
// 简写格式 #RGB -> #RRGGBB
|
|
405
|
+
fontColor = 'FF' + fontColor.split('').map(c => c + c).join('');
|
|
374
406
|
}
|
|
375
407
|
|
|
376
408
|
let font = {
|
|
377
409
|
name: typeof ff === 'number' ? luckyToExcel[ff] : ff,
|
|
378
410
|
family: 2, // 修改为更通用的字体族
|
|
379
411
|
size: Math.max(8, Math.min(72, fs)), // 限制字体大小范围
|
|
380
|
-
color: { argb: fontColor },
|
|
412
|
+
color: { argb: fontColor.toUpperCase() },
|
|
381
413
|
bold: luckyToExcel.num2bl(bl),
|
|
382
414
|
italic: luckyToExcel.num2bl(it),
|
|
383
415
|
underline: luckyToExcel.num2bl(ul),
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base64和File转换功能使用示例
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
fileToBase64,
|
|
7
|
+
base64ToFile,
|
|
8
|
+
base64ToBlob,
|
|
9
|
+
downloadBase64File,
|
|
10
|
+
MIME_TYPES
|
|
11
|
+
} from './fileUtils.js';
|
|
12
|
+
|
|
13
|
+
// 示例1: File转Base64
|
|
14
|
+
async function exampleFileToBase64() {
|
|
15
|
+
try {
|
|
16
|
+
// 假设有一个File对象
|
|
17
|
+
const fileInput = document.querySelector('input[type="file"]');
|
|
18
|
+
const file = fileInput.files[0];
|
|
19
|
+
|
|
20
|
+
if (file) {
|
|
21
|
+
const base64 = await fileToBase64(file);
|
|
22
|
+
console.log('转换后的Base64:', base64);
|
|
23
|
+
return base64;
|
|
24
|
+
}
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.error('File转Base64失败:', error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 示例2: Base64转File
|
|
31
|
+
function exampleBase64ToFile(base64String) {
|
|
32
|
+
try {
|
|
33
|
+
// 将Base64转换回File对象
|
|
34
|
+
const file = base64ToFile(
|
|
35
|
+
base64String,
|
|
36
|
+
'example.xlsx',
|
|
37
|
+
MIME_TYPES.EXCEL
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
if (file) {
|
|
41
|
+
console.log('转换后的File对象:', file);
|
|
42
|
+
console.log('文件名:', file.name);
|
|
43
|
+
console.log('文件大小:', file.size);
|
|
44
|
+
console.log('文件类型:', file.type);
|
|
45
|
+
return file;
|
|
46
|
+
}
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error('Base64转File失败:', error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 示例3: Base64转Blob
|
|
53
|
+
function exampleBase64ToBlob(base64String) {
|
|
54
|
+
try {
|
|
55
|
+
const blob = base64ToBlob(base64String, MIME_TYPES.EXCEL);
|
|
56
|
+
if (blob) {
|
|
57
|
+
console.log('转换后的Blob对象:', blob);
|
|
58
|
+
return blob;
|
|
59
|
+
}
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.error('Base64转Blob失败:', error);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 示例4: 直接下载Base64文件
|
|
66
|
+
function exampleDownloadBase64File(base64String) {
|
|
67
|
+
try {
|
|
68
|
+
downloadBase64File(
|
|
69
|
+
base64String,
|
|
70
|
+
'downloaded-file.xlsx',
|
|
71
|
+
MIME_TYPES.EXCEL
|
|
72
|
+
);
|
|
73
|
+
console.log('文件开始下载...');
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.error('下载失败:', error);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 示例5: 在Luckysheet对话框中的实际应用
|
|
80
|
+
function exampleInDialogUsage() {
|
|
81
|
+
// 模拟对话框提交时的数据处理
|
|
82
|
+
const mockResponse = {
|
|
83
|
+
data: '{"sheet1":[[{"v":"测试数据"}]]}',
|
|
84
|
+
json: [{ sheet1: [[{ v: "测试数据" }]] }],
|
|
85
|
+
file: new File([], 'test.xlsx'), // 模拟的原始File对象
|
|
86
|
+
base64: 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,UEsDBAoAAAAAALJ...' // 模拟的Base64数据
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// 进行双向转换验证
|
|
90
|
+
const convertedFile = base64ToFile(mockResponse.base64, 'converted.xlsx');
|
|
91
|
+
const reConvertedBase64 = fileToBase64(convertedFile);
|
|
92
|
+
|
|
93
|
+
console.log('原始File:', mockResponse.file);
|
|
94
|
+
console.log('转换后的File:', convertedFile);
|
|
95
|
+
console.log('重新转换的Base64:', reConvertedBase64);
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
original: mockResponse,
|
|
99
|
+
converted: convertedFile,
|
|
100
|
+
reconverted: reConvertedBase64
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 导出所有示例函数
|
|
105
|
+
export {
|
|
106
|
+
exampleFileToBase64,
|
|
107
|
+
exampleBase64ToFile,
|
|
108
|
+
exampleBase64ToBlob,
|
|
109
|
+
exampleDownloadBase64File,
|
|
110
|
+
exampleInDialogUsage
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// 默认导出
|
|
114
|
+
export default {
|
|
115
|
+
fileToBase64,
|
|
116
|
+
base64ToFile,
|
|
117
|
+
base64ToBlob,
|
|
118
|
+
downloadBase64File,
|
|
119
|
+
MIME_TYPES,
|
|
120
|
+
examples: {
|
|
121
|
+
fileToBase64: exampleFileToBase64,
|
|
122
|
+
base64ToFile: exampleBase64ToFile,
|
|
123
|
+
base64ToBlob: exampleBase64ToBlob,
|
|
124
|
+
downloadBase64File: exampleDownloadBase64File,
|
|
125
|
+
inDialogUsage: exampleInDialogUsage
|
|
126
|
+
}
|
|
127
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 文件转换工具类
|
|
3
|
+
* 提供常用的文件格式转换功能
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* File对象转Base64 DataURL
|
|
8
|
+
* @param {File|Blob} file 文件对象
|
|
9
|
+
* @returns {Promise<string>} 返回Base64字符串的Promise
|
|
10
|
+
*/
|
|
11
|
+
export function fileToBase64(file) {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
if (!file) {
|
|
14
|
+
reject(new Error('文件对象不能为空'));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const reader = new FileReader();
|
|
19
|
+
reader.onload = (e) => {
|
|
20
|
+
resolve(e.target.result);
|
|
21
|
+
};
|
|
22
|
+
reader.onerror = (error) => {
|
|
23
|
+
reject(error);
|
|
24
|
+
};
|
|
25
|
+
reader.readAsDataURL(file);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Base64 DataURL转File对象
|
|
31
|
+
* @param {string} base64 Base64数据URL字符串
|
|
32
|
+
* @param {string} filename 文件名
|
|
33
|
+
* @param {string} mimeType 文件MIME类型,默认为Excel类型
|
|
34
|
+
* @returns {File|null} 返回File对象,失败时返回null
|
|
35
|
+
*/
|
|
36
|
+
export function base64ToFile(base64, filename, mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
|
|
37
|
+
try {
|
|
38
|
+
if (!base64 || !filename) {
|
|
39
|
+
console.warn('Base64或文件名不能为空');
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 移除Base64数据URL的前缀,获取纯Base64数据
|
|
44
|
+
const base64Data = base64.replace(/^data:.*?;base64,/, '');
|
|
45
|
+
|
|
46
|
+
// 将base64转换为二进制数组
|
|
47
|
+
const byteCharacters = atob(base64Data);
|
|
48
|
+
const byteNumbers = new Array(byteCharacters.length);
|
|
49
|
+
|
|
50
|
+
for (let i = 0; i < byteCharacters.length; i++) {
|
|
51
|
+
byteNumbers[i] = byteCharacters.charCodeAt(i);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const byteArray = new Uint8Array(byteNumbers);
|
|
55
|
+
|
|
56
|
+
// 创建Blob对象
|
|
57
|
+
const blob = new Blob([byteArray], { type: mimeType });
|
|
58
|
+
|
|
59
|
+
// 创建File对象
|
|
60
|
+
const file = new File([blob], filename, {
|
|
61
|
+
type: mimeType,
|
|
62
|
+
lastModified: Date.now()
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return file;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error('Base64转File失败:', error);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Base64转Blob对象
|
|
74
|
+
* @param {string} base64 Base64数据URL字符串
|
|
75
|
+
* @param {string} mimeType 文件MIME类型
|
|
76
|
+
* @returns {Blob|null} 返回Blob对象,失败时返回null
|
|
77
|
+
*/
|
|
78
|
+
export function base64ToBlob(base64, mimeType = 'application/octet-stream') {
|
|
79
|
+
try {
|
|
80
|
+
if (!base64) {
|
|
81
|
+
console.warn('Base64不能为空');
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const base64Data = base64.replace(/^data:.*?;base64,/, '');
|
|
86
|
+
const byteCharacters = atob(base64Data);
|
|
87
|
+
const byteNumbers = new Array(byteCharacters.length);
|
|
88
|
+
|
|
89
|
+
for (let i = 0; i < byteCharacters.length; i++) {
|
|
90
|
+
byteNumbers[i] = byteCharacters.charCodeAt(i);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const byteArray = new Uint8Array(byteNumbers);
|
|
94
|
+
const blob = new Blob([byteArray], { type: mimeType });
|
|
95
|
+
|
|
96
|
+
return blob;
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.error('Base64转Blob失败:', error);
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 下载Base64数据为文件
|
|
105
|
+
* @param {string} base64 Base64数据URL
|
|
106
|
+
* @param {string} filename 下载的文件名
|
|
107
|
+
* @param {string} mimeType 文件MIME类型
|
|
108
|
+
*/
|
|
109
|
+
export function downloadBase64File(base64, filename, mimeType) {
|
|
110
|
+
try {
|
|
111
|
+
const file = base64ToFile(base64, filename, mimeType);
|
|
112
|
+
if (file) {
|
|
113
|
+
const url = URL.createObjectURL(file);
|
|
114
|
+
const link = document.createElement('a');
|
|
115
|
+
link.href = url;
|
|
116
|
+
link.download = filename;
|
|
117
|
+
document.body.appendChild(link);
|
|
118
|
+
link.click();
|
|
119
|
+
document.body.removeChild(link);
|
|
120
|
+
URL.revokeObjectURL(url);
|
|
121
|
+
}
|
|
122
|
+
} catch (error) {
|
|
123
|
+
console.error('下载Base64文件失败:', error);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* 常用文件MIME类型映射
|
|
129
|
+
*/
|
|
130
|
+
export const MIME_TYPES = {
|
|
131
|
+
EXCEL: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
132
|
+
PDF: 'application/pdf',
|
|
133
|
+
WORD: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
134
|
+
IMAGE_JPEG: 'image/jpeg',
|
|
135
|
+
IMAGE_PNG: 'image/png',
|
|
136
|
+
IMAGE_GIF: 'image/gif',
|
|
137
|
+
TEXT: 'text/plain',
|
|
138
|
+
JSON: 'application/json'
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export default {
|
|
142
|
+
fileToBase64,
|
|
143
|
+
base64ToFile,
|
|
144
|
+
base64ToBlob,
|
|
145
|
+
downloadBase64File,
|
|
146
|
+
MIME_TYPES
|
|
147
|
+
};
|
|
@@ -160,8 +160,8 @@ export default {
|
|
|
160
160
|
|
|
161
161
|
// 这里可以使用file对象进行上传等操作
|
|
162
162
|
// 例如:uploadFile(file);
|
|
163
|
-
const fileName = `电子表格_${new Date().getTime()}.xlsx`;
|
|
164
|
-
saveAs(file, fileName);
|
|
163
|
+
// const fileName = `电子表格_${new Date().getTime()}.xlsx`;
|
|
164
|
+
// saveAs(file, fileName);
|
|
165
165
|
})
|
|
166
166
|
.catch((error) => {
|
|
167
167
|
console.error("生成Excel文件对象失败:", error);
|