前言
在日常开发中难免遇到,处理数据量比较大时,或者是针对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.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
   | 
  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",      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",                 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版本比较低
1 2
   |  fs.root!.getFile(`订单.xls`, { create: true }, (fileEntry) => {})
 
  | 
 
以下是常见后缀名,供参考:

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