使用FileSaver+xlsx实现前端导出Excel表格

1,082 阅读3分钟

引言:

在笔者开发的某项目测试阶段计划采用“飞行棋测试方法”(笔记所在组的测试团队大哥首创),在测试前期同时也是首要环节要根据后台YAPI接口来写“因子表格”。表格的内容和形式如下:

问题来了!第一,这个“因子表格”编写的依据是后台接口开发人员定义的YAPI接口文档,而表格的使用人员是测试人员。那么这个表格谁来写?接口开发人员和测试人员相互“甩锅”。第二,即便有人愿意写这个表格,写起来也得几分钟吧,那么多的接口累计起来也是蛮耗时的。

团队小伙伴建议:既然YAPI能够导出,就可以根据导出的文档生成Excel。我们可以写一个工具,让程序来做这样事情。

1."因子表格"生成工具

1.1工具的设计以及界面的UI表现

工具在功能上应该满足以下几点:

  1. 允许用户选择要解析接口的json文件
  2. 允许用户对接口进行选择:

由于我们平台的接口使用的是Restful规范的,所以按照POST,PUT,GET,DELETE对接口进行分类;

在每一个分类下可以选择对应的接口

  1. 允许用户预览生成的结果
  2. 允许用户对生成的结果进行导出

1.2核心功能思路及实现

1.2.1 流程图

工具的流程如下:

1.2.2实现思路

来看一下每一步骤的实现思路:

1.选择json文件:使用文件上传组件 ,我这里使用的是el-upload;获取文件后要读取文件数据为后续解析环节准备。

2.筛选接口:使用两个下拉选。一个是选择Restful接口的类型,另一个是选择某类型下的接口,组件选用el-select。

3.预览生成结果:选择某个接口后获得此接口的参数并解析,生成列表表头和数据,组件使用el-table。

4.导出表格:需要额外的npm包来支持,FileSaver+xlsx

1.2.3 具体实现

(1)读取json文件的数据

使用FileReader读取文件数据

const reader = new FileReader();
reader.readAsText(file);
reader.onloadend = function (res) {
  that.$message({message:'读取文件成功',type:'success'})
  const apiJson = JSON.parse(res.target.result)
}

FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 FileBlob 对象指定要读取的文件或数据。

readAsText 方法可以将 Blob 或者 File 对象转根据特殊的编码格式转化为内容(字符串形式)。所以需要JSON.parse转为对象。

(2)筛选接口

第一个类型下拉选的数据固定写死即可:

第二个要处理的接口和前面的类型是联动的,应该有4组,所以需要组织数据:

首选将接口分成四类:

let interfaceArrPost = []
let interfaceArrGet = []
let interfaceArrPut = []
let interfaceArrDelete = []
const filter = (list, type) => {
  const res = list.filter(item => {
    if (item.method === type) {
      return item
    }
  })
  return res
}
apiJson.forEach(element => {
  // element为整个yapi下的大分类
  // 在大分类下寻找所有的post接口
  const arrPost = filter(element.list, 'POST')
  const arrGet = filter(element.list, 'GET')
  const arrPut = filter(element.list, 'PUT')
  const arrDelete = filter(element.list, 'DELETE')
  interfaceArrPost = interfaceArrPost.concat(arrPost)
  interfaceArrGet = interfaceArrGet.concat(arrGet)
  interfaceArrPut = interfaceArrPut.concat(arrPut)
  interfaceArrDelete = interfaceArrDelete.concat(arrDelete)
});

生成4种分类的接口下拉选数据以及接口id和json对应的map(方便选择某接口后获得此接口的json):

const generateListAndMap = (sourceInterfaceList, targetList, targetMap) => {
  sourceInterfaceList.forEach(item => {
    // id 和接口名对应的list
    targetList.push({
      value: item._id,
      label: item.title
    })
    // id与json对应的map
    targetMap.set(item._id, item)
  })
}
generateListAndMap(interfaceArrPost, that.idJsonListPost, that.idJsonMap)
generateListAndMap(interfaceArrGet, that.idJsonListGet, that.idJsonMap)
generateListAndMap(interfaceArrPut, that.idJsonListPut, that.idJsonMap)
generateListAndMap(interfaceArrDelete, that.idJsonListDelete, that.idJsonMap)
// 默认选择POST方法的接口
that.idJsonListGeneric = that.idJsonListPost
that.searchMethod = 'POST'

(3)预览生成结果

已GET类型接口为例:

 handleGet (json) {
   const arr = json.req_query
   let tableHeader = []
   let tableData = [{}, {}]
   arr.forEach(item => {
     tableHeader.push({
       prop: item.name,
       label: item.desc
     })
     const isRequired = item.required === '1'
     tableData[0][item.name] = `${item.name} `
     tableData[1][item.name] = `${isRequired}`
   })
   tableHeader.unshift({
     prop: 'hideType',
     label: ''
   })
   tableData[0]['hideType'] = '参数名'
   tableData[1]['hideType'] = '是否必须'
   this.tableHeader = tableHeader;
   this.tableData = tableData;
   this.showTable = true;
 },

代码运行结果:

(4)导出表格

借助File Saver和xlsx来实现:

import FileSaver from "file-saver";
import { utils, write } from "xlsx";
exportExcel () {
  let name = '表格'
  /* generate workbook object from table */
  //  .table要导出的是哪一个表格
  var wb = utils.table_to_book(document.querySelector(".table"));
  /* get binary string as output */
  var wbout = write(wb, {
    bookType: "xlsx",
    bookSST: true,
    type: "array"
  });
  try {
    //  name+'.xlsx'表示导出的excel表格名字
    FileSaver.saveAs(
      new Blob([wbout], { type: "application/octet-stream" }),
      name + ".xlsx"
    );
  } catch (e) {
    if (typeof console !== "undefined") console.log(e, wbout);
  }

utils.table_to_book根据table列表创建一个workbook;write方法根据workbook生成字节数据;FileSaver.saveAs用于保存数据并生成.xlsx文件。

1.3 运行效果

工具整体运行界面:

点击导出表格:

2.总结和思考

总结: 读取json文件用到了FileReader api; 在生成Excel表格的时候需要借助File Saver和xlsx来实现。

思考: 前端导出表格只适用于你想导出的表格仅包含table列表中展示的内容;如果导出的表格需要展示table列表没有的内容则需要后台导出。

3.参考资料

developer.mozilla.org/zh-CN/docs/…

blog.csdn.net/weixin_4242…

www.npmjs.com/package/xls…