需求小能手——导出Excel文件

lxf2023-04-12 22:32:02

开启AdminJS成长之旅!这是我参与「AdminJS · 2 月更文挑战」的第26天,点击查看活动详情

前言

文件导出需求在后端管理系统等项目非常的常见,一般后端会提供下接口,前端封装一个专门下载文件的请求方式去下载文件,如果后端没有对应接口,只是返回数据,这时候就需要前端自己去转换导出,将json数据转换为excel。

实现

要想实现该功能,我们要借助两样工具:

  • file-saver:用来保存blob文件流,生成文件。具体通过其中的saveAs函数来生成,ts类型如下:
   function saveAs(data: Blob | string, filename?: string, options?: FileSaverOptions): void;

该函数接收三个参数:文件流,文件名称,相关设置。后两个参数是可选的。

  • xlsx:用于生成.xlsx文件,通过xlsx.write()接口来生成文件,该api的ts类型如下:
   write(data: WorkBook, opts?: WritingOptions): any;

接收两个参数:数据,配置项。配置项是可选的。 了解了上面的两个工具,现在就开始我们的实现之旅。

  1. 首先安装file-saver、xlsx依赖。
  2. 确认配置项,也就是函数的参数,这里我们设置一下配置项,用接口声明类型:
   interface IExcelParams {
      //表头
      header: string[]
      //数据
      data: any
      autoWidth?: boolean
      filename?: string
      //文件类型
      bookType?: string
      multiHeader?: string[][]
      merges?: any[]
    }

这里主要是header表格与data数据。

3.利用xlsx创建一个工作表对象,对于该对象有两个属性是必需的SheetNames(工作蒲名称列表)与Sheets(每个工作蒲对应的模型)。

//设置类
  class Workbook{
  SheetNames: string[] = []
  Sheets: { [sheet: string]: WorkSheet } = {}
}
//实例化工作表
const wb = new Workbook()

4.接下来就是创建工作表的模型,对于工作表而言,列和行都有对应的位置坐标,所以我们首先设定列和行的范围,然后循环生成单元格。范围的设置是一个对象,具体用法如下:

   const range = {
   //开始 列与行的范围
    s: {
      c: 0,
      r: 0
    },
    //结束列与行的范围
    e: {
      c: 10,
      r: 10
    }
  }

设定好范围之后再去循环二维数组数据,利用XLSX.utils.encode_cell去设置每一个单元格对应的数据。

5.得到设置好的wb,然后用xlsx.write去生成文件。

    //bookType为类型 这里就是.xlsx类型
   const wbout = XLSX.write(wb, {
    bookType: bookType as any,
    bookSST: false,
    type: 'binary'
  })

6.最后利用saveAs导出文件,这里我们需要利用new Blob将wbout变成文件流。

   import { saveAs } from 'file-saver'
   saveAs(
    new Blob([s2ab(wbout)], {
      type: 'application/octet-stream'
    }),
    `${filename}.${bookType}`
  )

经过以上步骤我们就能将后端返回的json数据,导出excel文件。

总结

将后端json数据导出excel文件,需要利用file-saver、xlsx两个工具,当然这两个工具还有其他功能,有兴趣的可以研究下。