前端快速实现数据和表格的Excel导出

138 阅读2分钟

前言

最近在开发一个数据展示的 Table页面需要增加一个Excel导出功能,用于运营人员做数据汇总。数据不算大,比较大的数据导出不建议前端实现(浏览器会崩), 但后端要求这个功能让前端来实现,故实现后记录这个方案

一些细节

由于是通过分页得到数据,这里通过后端的Total字段得到总数据量,后结合Promise,计算总共要获取的数据页数,获取所有数据后处理合并后进行导出。

Xlsx

这里使用sheetjs 这个库来实现核心的 xlsx文件导出, 对于导出它主要有以下几种方法:

Dom直接导出

import { utils, writeFileXLSX } from 'xlsx'

//raw 内容格式会被处理为纯文本 主要是为了防止出现乱码的情况
const wb = utils.table_to_book(Dom, { raw: true })

  //需要 取当前年月日时分秒的数据
writeFileXLSX(wb, `报表.xlsx`)

对象或按数组结构写出

import { utils, writeFile } from 'xlsx'
let book = utils.book_new();
//对象形式写法 对象数组
// const sheet1 = utils.json_to_sheet([{ "id": "1", "ok": "123" }]);
//按行 二维数组
// const sheet2 = utils.aoa_to_sheet([["a", "b", "c"], [1, 2, 3]]);
const sheet2 = utils.aoa_to_sheet(data);
utils.book_append_sheet(book, sheet2, "异常工时登记");
writeFile(book, `异常工时登记报表${exportDateName}.xlsx`);

数据处理和导出

this.CurrentData = [];
//先计算当前 总条数是否大于100行
if (this.Total > this.MaxGetTotal) {
  //取出总共要循环求几次数据
  const num = Math.ceil(this.Total / this.MaxGetTotal);
  const requestAry = []; //存储所有基于Promise封装的请求
  for (let i = 1; i <= num; i++) {
    requestAry.push(excelGetList(i, this.MaxGetTotal)); //传递Page Rows
  }
  //promise并发  to函数可以参考源码共读这一期内容噢https://juejin.cn/post/7138263385686147080
  const [err, res] = await to(Promise.all(requestAry));
  //拼接数据
  res.forEach(
    (item) =>
    (this.CurrentData = this.CurrentData.concat(
      item.data.Data
    ))
  );

  //不分页逻辑
} else {
  // 不必分页那么 只拿一次数据就好
  const [err, res] = await to(
    excelGetList(1, this.MaxGetTotal)
  );
  this.CurrentData = res.data.Data
}

//...省略对于数据中对象和数组转换 以及一些判断

//创建一个空工作簿
const book = utils.book_new();
//创建一个工作表sheet 这里的main 就是你处理好的 二维数组或者对象数据
const sheet2 = utils.aoa_to_sheet(main);

//加入工作表到工作簿中
utils.book_append_sheet(book, sheet2, "工时登记");
writeFile(book, `工时登记报表.xlsx`);