参考资料出于:挥刀北上

前端如何将JSON数据导出为excel文件

前端人员在开发时,有时为了满足用户需求,需要下载excel文件。这里通常有两种做法,一种是后端工程师将数据转化为excel,然后前端进行下载即可,还有一种方式,前端请求需要下载的数据,在浏览器端生成excel文件,然后进行下载

此处就以前端导出excel的方式进行说明 —>本人用TS写法,但实际上只是多了类型声明,不用的删除即可

Ⅰ-代码示例与注释

```jsx //1、定义导出文件名称 var filename = “write.xlsx”; // 定义导出数据 此处需传入数组类型的数据 var data = dataSource // 定义excel文档的名称 var ws_name = “SheetJS”; // 初始化一个excel文件 var wb = XLSX.utils.book_new(); // 初始化一个excel文档,此时需要传入数据 var ws = XLSX.utils.aoa_to_sheet(data); // 将文档插入文件并定义名称 XLSX.utils.book_append_sheet(wb, ws, ws_name); // 执行下载 XLSX.writeFile(wb, filename);

//自己模拟服务端数据 const dataSource = [ { agentTotalAmt: ‘999’, agentId: ‘hongjilin’, name: ‘努力学习的汪’, cooperationStatus: 2, month: ‘202106’, totalCompany: 666, qty: 999, increaQty: 666, totalAmt: 9999, incomeType: ‘收款方式’, algorithm: ‘帅的很’, }, { agentTotalAmt: ‘888’, agentId: ‘jilinhong’, name: ‘特别努力学习的单身汪’, cooperationStatus: 2, month: ‘202107’, totalCompany: 666, qty: 1111, increaQty: 111, totalAmt: 1111, incomeType: ‘收款方式’, algorithm: ‘可怜得很’, }, ];

  1. > 使用xlse导出文件时,json数据需要转换为数组,通常为二维数组,通常第一行为表头,如:**_`['第一列','第二列','第三列']`*_,然后就是使用xlse的步骤了,通常分为如下几个步骤:
  2. > 1、调用XLSX.utils.book_new()初始化excel文件。
  3. > 2、调用XLSX.utils.aoa_to_sheet(data),初始化excel文档,此时需要传入数据,数据为二维数组,第一行通常为表头。
  4. > 3、调用XLSX.utils.book_append_sheet(wb, ws, ws_name),将文档插入excel文件,并为文档命名。
  5. > 4、调用XLSX.writeFile(wb, filename)下载excel文件,并为excel文件命名。
  6. <a name="da12ef55"></a>
  7. # Ⅱ-本人在自己React中使用
  8. <a name="9d358e52"></a>
  9. ## 1、直接将服务端JSON字段导出成表格
  10. > 本人项目代码中会多处使用该导出功能,所以会进行封装
  11. > 1. 工具包封装(函数实现主体)
  12. > ```tsx
  13. import XLSX from 'xlsx';
  14. class Tool {
  15. /**
  16. * 导出成XLSX文件
  17. * @param dataSource 传入的对象数组
  18. * @param fileName 生成的文件名
  19. * @param title 设置列名,如果不传入则默认将对象数组的key当作表头
  20. */
  21. OnExport = (dataSource: Array<object>, fileName: string, title?: any) => {
  22. //当传入的数组长度为0,直接退出 此处加[?]是因为防错,防止真有人乱传参数
  23. //[!dataSource ]是防止传入undefined导致函数执行错误 -->即使已经用TS限制了,但有时服务端给的值还真不一定对
  24. if (!dataSource || dataSource?.length == 0) return;
  25. let data = dataSource;
  26. let head = Object.keys(data[0]);
  27. //取出json格式数据中的[value]值
  28. data = data.map((e) => Object.values(e));
  29. //如果不传入[title],则用keys当表头
  30. data.unshift(title || head);
  31. //文件名
  32. let filename = `${fileName}.xlsx`;
  33. // let ws_name = "xxx";
  34. let wb = XLSX.utils.book_new();
  35. let ws = XLSX.utils.aoa_to_sheet(data);
  36. XLSX.utils.book_append_sheet(wb, ws);
  37. XLSX.writeFile(wb, filename);
  38. };
  39. }
  40. export const tool = new Tool();
  41. export default Tool;
  1. 调用

```jsx //导入工具包 import { Tool } from ‘~/utils’; const tools = new Tool();

//[this.manage.date]是一个时间数据 //[this.datas]是要导出的数据 —>通常是服务端给定的数据,经过我们处理后成为如[Ⅰ]中示例代码的那种格式

exportXlsx = () => { //用于拼接月份 const month = this.manage.date.format(‘MM’); //没有数据能导出时给出提示 —>此处调用的是封装好的[信息提示]组件,同学们可以忽略此行代码 if (this.datas?.length == 0) SuperNotification.warning({ msg: ‘无数据可导出’}); //调用工具函数 tools.OnExport(toJS(this.datas), ${month}月份的数据表); };

———————- 将其绑定于点击事件上 ————————————————————

  1. > [`this.manage.date`]是一个时间数据<br />
  2. [`this.datas`]是要导出的数据 -->通常是服务端给定的数据,经过我们处理后成为如[`Ⅰ`]中示例代码的假数据那种格式
  3. > 3. 成功截图xlsx文件查看![](JavaScirpt%E5%B7%A5%E5%85%B7%E5%B0%81%E8%A3%85%E4%B8%AD%E7%9A%84%E5%9B%BE%E7%89%87/image-20210721155153046.png#alt=image-20210721154626462)
  4. <a name="b739777d"></a>
  5. ## 2、筛选数据且列表头转换文字
  6. > 1. 定义:
  7. > ```typescript
  8. import XLSX from 'xlsx';
  9. class Tool {
  10. /**
  11. * @param data 需要处理的数组
  12. * @param DICT 传入表头字段对应文字对象
  13. * test: CHANNELADMIN:{name:'姓名', username:'用户名'}
  14. * const { dataSource, titles } = tools.FilterDataSource(toJS(this.source.tableList), CHANNELADMIN)
  15. * @returns { dataSource, titles }
  16. */
  17. FilterDataSource = (
  18. data: Array<object>,
  19. DICT: object
  20. ): { dataSource: Array<object>; titles: Array<string> } => {
  21. //当传入的数组长度为0或者传入的参数错误,直接退出
  22. if (!data || data?.length == 0) return;
  23. let titles = new Array();
  24. //取出第一列表头,去除无用列且转换为中文
  25. Object.keys(data[0]).map((key) =>
  26. !!DICT[key] ? titles.push(DICT[key]) : null
  27. );
  28. //过滤数据中的无用列
  29. const dataSource = data.map((item) => {
  30. // item =toJS(item) //Proxy不能直接删除,需要转为js对象,
  31. Object.keys(item).map((key) => {
  32. if (!DICT[key]) delete item[key];
  33. });
  34. return item;
  35. });
  36. return {
  37. titles,
  38. dataSource,
  39. };
  40. };
  41. /** 导出成XLSX文件*/
  42. OnExport = (dataSource: Array<object>, fileName: string, title?: any) => {
  43. ...
  44. };
  45. }
  46. export const tool = new Tool();
  47. export default Tool;
  1. 调用

```jsx //导入工具包 import { Tool } from ‘~/utils’; const tools = new Tool(); const CONSTS={ //需要自己写好一个与字段对应的对象 key:字段名 value:自定义文字 name:’努力学习的汪’, type:’永远的学生’, id:’学号’ }

exportXlsx = () => { //注意,需要传入的数组不能是Proxy类型的!!! const { dataSource, titles } = tools.FilterDataSource(arr, CONSTS); //调用导出XLSX文件函数 tools.OnExport(dataSource, 表格数据, titles); };

———————- 将其绑定于点击事件上 ———————————————————— ```

  1. 成功示例

将json数据导出为excel文件 - 图1

Ⅲ-导出成功

  1. 点击导出下载成功

将json数据导出为excel文件 - 图2

当然,有的浏览器是直接下载不会给出下载提示

  1. OK了,其实不止在React中能使用,在Vue甚至原生js都可以调用这个函数