记录一次 VUE2.0 element el-table(多级表头,复杂的表格格式) 导出excel的过程

3,143 阅读2分钟
  1. 首先用sheetjs 生成excel文件结构(默认已安装vue element环境)
安装sheetjs

sheetjs 文档 github.com/SheetJS/she…

yarn add xlsx
在项目中引入
import XLSX from 'xlsx'
在methods中定义方法
exportTable(){
    const $table = this.$refs.tableDataRef.$el // 当前表格的dom元素
      const workbook = XLSX.utils.table_to_book($table, { raw: true }) // 此方法根据dom结构生成excel文档
      const wscols = [ // 定义每列的宽度 我这里是16列
        { wch: 19 },
        { wch: 19 },
        { wch: 19 },
        { wch: 19 },
        { wch: 19 },
        { wch: 19 },
        { wch: 19 },
        { wch: 19 },
        { wch: 19 },
        { wch: 19 },
        { wch: 19 },
        { wch: 19 },
        { wch: 19 },
        { wch: 19 },
        { wch: 19 },
        { wch: 19 }
      ]
      workbook.Sheets[workbook.SheetNames[0]]['!cols'] = wscols
      const wbout = XLSX.write(workbook, {  // 此时wbout 是一个拥有结构的excel文件 可以导出看下结构
        bookType: 'xlsx',
        bookSST: true,
        type: 'array' // 我这里生成的是array格式 还有其他格式 比如file 详细看文档
      })
      
      .......
}
根据结构添加样式

一开始是使用xlsx-style这个插件 后来发现坑很多 不推荐使用

我们根据 xlsx-populate 这个工具进行样式添加 附上文档 www.npmjs.com/package/xls…

因为是纯前端导出excel 这里使用的是 xlsx-populate的js文件 cdn地址: cdn.bootcdn.net/ajax/libs/x…

直接下载保存 在本地引入 xlsx-populate引入后会挂载到window对象上

使用xlsx-populate读取excel

设置表格标题样式
exportTable(){
....
const wbout = XLSX.write(workbook, {  
        bookType: 'xlsx',
        bookSST: true,
        type: 'array' 
      })
    window.XlsxPopulate.fromDataAsync(wbout).then((res) => {
        const currentExcel = res.sheet(0) //获取当前excel文件中的第一个sheet 也可以由多个具体看文档
        currentExcel.cell('A1').style({  //设置表头样式
          bold: true,
          fontSize: 18,
          border: {
            color: '000000',
            style: 'thin'
          },
          horizontalAlignment: 'center',
          verticalAlignment: 'center',
          wrapText: true,
          shrinkToFit: true,
          justifyLastLine: true
        })
        .......
}
设置表头样式

因为我这边表头属于固定列 所以直接用range 方法直接选择一个区域 设置统一样式

currentExcel.range('A2:J3').style({ 
          bold: true,
          fontSize: 10.5,
          border: {
            color: '000000',
            style: 'thin'
          },
          horizontalAlignment: 'center',
          verticalAlignment: 'center',
          wrapText: true,
          shrinkToFit: true,
          justifyLastLine: true
        
设置数据行样式

需计算数据开始位置 我的是A3开始 到 J + 数据行总数 - 1

        const maxDatalength = `A3:J${currentExcel._rows.length - 1}`
        currentExcel.range(maxDatalength).style({ // 数据行样式
          fontSize: 10.5,
          border: {
            color: '000000',
            style: 'thin'
          },
          horizontalAlignment: 'center',
          verticalAlignment: 'center',
          wrapText: true,
          shrinkToFit: true,
          justifyLastLine: true
        })
       
导出为Excel
        res.outputAsync().then(function (blob) { // 最后调用浏览器原生的导出功能
          if (window.navigator && window.navigator.msSaveOrOpenBlob) {
            // If IE, you must uses a different method.
            window.navigator.msSaveOrOpenBlob(blob, 'out.xlsx')
          } else {
            const url = window.URL.createObjectURL(blob)
            const a = document.createElement('a')
            document.body.appendChild(a)
            a.href = url
            a.download = `${_this.title}.xlsx`
            a.click()
            window.URL.revokeObjectURL(url)
            document.body.removeChild(a)
          }
        })
      })