uniapp打包App实现导出xlsx

The局外人 Lv Max

前言

在日常开发中难免遇到,处理数据量比较大时,或者是针对table表格数据,想后续查看,编辑,备份操作时,通常需要导入为xlsx文件,pc端可以通过xlsx的npm包进行导出,但是App想实现导出xlsx又应该如何操作呢?

1. 获取写文件操作对象✍️

这里摒弃大部分情况下后端返回Blob的数据流格式,想想如何把一个普通的数组对象转换成表结构,导出xlsx呢?

这里介绍一下HTML5+API Reference的IO模块管理本地文件系统。

1
2
// 请求手机本地文件系统对象
void plus.io.requestFileSystem( type, succesCB, errorCB );

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
// 第一个参数为本地文件系统常量
// 第二个参数为成功的回调
plus.io.requestFileSystem(plus.io.PUBLIC_DOWNLOADS,(fs) => {
// 拿到fs模块进行文件操作
fs.root!.getFile(`订单.xlsx`, { create: true }, (fileEntry) => {
fileEntry.createWriter((writer) => {
writer.write();
// 写入文件是否成功
writer.onwrite = (e: any) => {
// 写入成功的回调
}
}
})

拿到fs模块可进行文件操作,找到root(文件系统的根目录),然后调用getFile()函数创建或打开文件,{ create: true },代表

在本地打开一个 订单.xlsx的文件的文件,有就打开,没有就在本地创建。然后获取文件关联的写文件操作对象FileWriter,注: writer.write();只能传入字符串。

2. 生成HTML字符串👊

以上 writer.write();可以写入HTML字符串,我们只需把想要展示的数据转成HTML字符串即可。

附上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// 可通过行内样式,调整布局
// 请求后端接口获取数据比如[{name:'刘德华',age:20},{name:'张学友',age:30}]
let newHtmlStr = `
<html>
<head>
</head>
<body>
<table border="1">
<tr style="height:50px;font-size:16px;font-weight:bold;font-family: 微软雅黑;">
<td style="background-color: skyblue;">收货日期</td>
<td style="background-color: skyblue;">收货时间</td>
<td style="background-color: skyblue;">ID</td>
<td style="background-color: skyblue;">团队名</td>
<td style="background-color: skyblue;">商品分类</td>
<td style="background-color: skyblue;">商品规格</td>
<td style="background-color: skyblue;">商品名</td>
<td style="background-color: skyblue;">采购数量</td>
<td style="background-color: skyblue;">采购单位</td>
<td style="background-color: skyblue;">采购方备注</td>
<td style="background-color: skyblue;">适配配注</td>
<td style="background-color: skyblue;">订单状态</td>
</tr>
${downList
.map((item) => {
return `
<tr style="font-family: 微软雅黑;">
<td>${item.orderTime}</td>
<td>${item.receiveTime}</td>
<td>${item.bgroupId}</td>
<td>${item.groupName}</td>
<td>${item.categoryName}</td>
<td>${item.categoryAncestor}</td>
<td>${item.goodName}</td>
<td>${item.amount}</td>
<td>${item.unitWeighName}</td>
<td>${item.remark}</td>
<td>${item.allowContent}</td>
<td>${orderStatus(item.orderStatus)}</td>
</tr>
`;
})
.join("")}
</table>
</body>

</html>
`;

3. 分享文件👇

3.1. 使用插件

最后通过uniapp插件市场的《安卓ios分享任意类型文件》实现唤起系统分享面板

插件地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 导入插件
const FileShare = uni.requireNativePlugin("life-FileShare");
// 使用插件自动唤起系统分享面板
FileShare.render(
{
type: "SYSTEM", //QQ为QQ,微信为WX,系统默认是SYSTEM,不填写默认SYSTEM
filePath: plus.io.convertLocalFileSystemURL(
`file://${e.target.fileName}`
),
},
(result: any) => {
console.log(result);
},
(err: any) => {
console.log(err);
}
);

完整代码附上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
plus.io.requestFileSystem(
plus.io.PUBLIC_DOWNLOADS,
(fs) => {
fs.root!.getFile(`订单.xlxs`, { create: true }, (fileEntry) => {
fileEntry.createWriter((writer) => {
let newHtmlStr = `
<html>
<head>
</head>
<body>
<table border="1">
<tr style="height:50px;font-size:16px;font-weight:bold;font-family: 微软雅黑;">
<td style="background-color: skyblue;">收货日期</td>
<td style="background-color: skyblue;">收货时间</td>
<td style="background-color: skyblue;">ID</td>
<td style="background-color: skyblue;">团队名</td>
<td style="background-color: skyblue;">商品分类</td>
<td style="background-color: skyblue;">商品规格</td>
<td style="background-color: skyblue;">商品名</td>
<td style="background-color: skyblue;">采购数量</td>
<td style="background-color: skyblue;">采购单位</td>
<td style="background-color: skyblue;">采购方备注</td>
<td style="background-color: skyblue;">适配配注</td>
<td style="background-color: skyblue;">订单状态</td>
</tr>
${downList
.map((item) => {
return `
<tr style="font-family: 微软雅黑;">
<td>${item.orderTime}</td>
<td>${item.receiveTime}</td>
<td>${item.bgroupId}</td>
<td>${item.groupName}</td>
<td>${item.categoryName}</td>
<td>${item.categoryAncestor}</td>
<td>${item.goodName}</td>
<td>${item.amount}</td>
<td>${item.unitWeighName}</td>
<td>${item.remark}</td>
<td>${item.allowContent}</td>
<td>${orderStatus(item.orderStatus)}</td>
</tr>
`;
})
.join("")}
</table>
</body>

</html>
`;
writer.write(newHtmlStr);
// 写入文件是否成功
writer.onwrite = (e: any) => {
FileShare.render(
{
type: "SYSTEM", //QQ为QQ,微信为WX,系统默认是SYSTEM,不填写默认SYSTEM
filePath: plus.io.convertLocalFileSystemURL(
`file://${e.target.fileName}`
),
},
(result: any) => {
console.log(result);
},
(err: any) => {
console.log(err);
}
);
};
});
});
},
(err) => {
Toast("none", "文件系统访问失败");
}
);

3.2. 效果展示

以华为手机为例:


导出后的结果:

image.png

3.3. 注意点

针对一些人电脑上的wps或office版本比较低

1
2
// 可采用.xls以后缀名结尾
fs.root!.getFile(`订单.xls`, { create: true }, (fileEntry) => {})

以下是常见后缀名,供参考:

写在最后

本方案未必最优,可能还有其他方案,以文档为主,如有问题欢迎指出,本文章主要阐述开发中可能会遇到的需求,以及我个人的一些解决办法。希望对大家有一定的班助。😀😀😀😀😀

  • 标题: uniapp打包App实现导出xlsx
  • 作者: The局外人
  • 创建于 : 2024-05-15 09:18:35
  • 更新于 : 2024-05-15 09:18:57
  • 链接: https://dragon-xjy.gitee.io/2024/05/15/uniapp打包App导出xlsx/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
 评论