前言
在日常开发中难免遇到,处理数据量比较大时,或者是针对table表格数据,想后续查看,编辑,备份操作时,通常需要导入为xlsx文件,pc端可以通过xlsx的npm包进行导出,但是App想实现导出xlsx又应该如何操作呢?
1. 获取写文件操作对象✍️
这里摒弃大部分情况下后端返回Blob的数据流格式,想想如何把一个普通的数组对象转换成表结构,导出xlsx呢?
这里介绍一下HTML5+API Reference的IO模块管理本地文件系统。
// 请求手机本地文件系统对象
void plus.io.requestFileSystem( type, succesCB, errorCB );
具体代码
// 第一个参数为本地文件系统常量
// 第二个参数为成功的回调
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字符串即可。
附上代码:
// 可通过行内样式,调整布局
// 请求后端接口获取数据比如[{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分享任意类型文件》实现唤起系统分享面板
// 导入插件
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);
}
);
完整代码附上:
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. 效果展示
以华为手机为例:
导出后的结果:
3.3. 注意点
针对一些人电脑上的wps或office版本比较低
// 可采用.xls以后缀名结尾
fs.root!.getFile(`订单.xls`, { create: true }, (fileEntry) => {})
以下是常见后缀名,供参考:
写在最后
本方案未必最优,可能还有其他方案,以文档为主,如有问题欢迎指出,本文章主要阐述开发中可能会遇到的需求,以及我个人的一些解决办法。希望对大家有一定的班助。😀😀😀😀😀