vue3导出表格excel(支持多sheet页),并自定义导出样式

前期准备

npm install file-saver

npm install xlsx

npm install xlsx-js-style

先说一说这里为什么选择用xlsx-js-style插件设置导出excel的样式。因项目需要,我在网上找了很多关于导出excel自定义样式的文章,用的最多最普遍的插件就是xlsx-style,有一个比较麻烦的问题是在引用xlsx-style的时候会报错,这是官网上就已经写了的,解决方案一是改node-module中的源码,二是修改配置文件,但是我觉得这两种方法不是长久之计,而且xlsx-style已经许久没有更新和维护不确定是否会出现其它问题。官网上的解决方案我也试过,也安装过xlsx-style-medalsoft等其他插件,就是依旧报错,可能是不大支持vue3???有待研究...所以我就把xlsx-style抛弃啦

html代码

需要导出的表格要在table标签或者el-table标签加上id名(我在这使用table标签是根据需求和接口返回的数据来定的,如果接口数据是平常的数组套对象又不需要自定义标题用el-table是一样的),在导出的时候需要借助id名来找到对应的表格,这几个表格的数据都是从接口来的就不直接贴代码了。使用v-show="false"隐藏表格是因为页面上不需要显示表格,只是需要借助这个表格来导出。需要注意的是这里隐藏不能使用v-if,v-if="false"是不会渲染元素的,导出的时候就找不到这个元素。

点击全部导出按钮绑定的方法

<script lang="ts" setup>
import { ElMessageBox } from 'element-plus'
import { exportExcel } from '@/utils/exportExcel'

// 全部導出
const allExport = async () => {
  ElMessageBox.confirm('確定導出所有會計報表?', '導出提示', {
    confirmButtonText: '確定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(() => {
      const allTable = [
        {
          eleName: '#detail', //要导出的表格id
          title: '明細分類賬表' //sheet页名称
        },
        {
          eleName: '#trial',
          title: '試算平衡表'
        },
        {
          eleName: '#balance',
          title: '資產負債表'
        },
        {
          eleName: '#gainLoss',
          title: '損益表'
        }
      ]
      exportExcel(allTable, '總表') //导出的excel的名称
    })
    .catch(() => {})
}
</script>

/utils/exportExcel

import FileSaver from 'file-saver'
import * as XLSX from 'xlsx'//这是vue3导入XLSX的方法
import XLSXS from 'xlsx-js-style'

// 導出Excel文件的方法
export function exportExcel(allTable, excelName) {
  const xlsxParam = { raw: true } // 导出的内容只做解析,不进行格式转换 如果不设置该属性80%可能导出的是0.8 可自行测试
  
  let wb = XLSX.utils.book_new()
  // 循环添加每一个表格/sheet (如果是只有一个sheet页的话就不需要循环,直接添加进去就可以了)
  for (const item of allTable) {
      let sheet = XLSX.utils.table_to_sheet(document.querySelector(item.eleName), xlsxParam)
      XLSX.utils.book_append_sheet(wb, sheet, item.title)
  }
  //console.log(wb) //打印查看wb的结构 看下图

  // 循环找到对应的单元格修改样式
  for (const key in wb.Sheets) {
    if (key == '損益表') {
      for (const k in wb.Sheets[key]) {
        // 非!开头的属性都是单元格
        if (!k.startsWith('!')) {
          const td = wb.Sheets[key][k] 
          //td每一个是单元格对象 v:单元格内容 t:单元格内容类型如string s:单元格样式
          if (td.v.includes('(')) {
            // 設置字體顔色 帶括號的數字比如(1,000.00)改成紅色
            td.s = {
              font: {
                color: { rgb: 'ff0000' }
                // name: '仿宋',
                // sz: 20,
                // bold: true,
              }
              // border: {
                // top: {
                  // style: 'thin',
                  // color: { rgb: '000000' }
                // }
              // }
            }
          }
        }
      }
    }
  }

  const wbout = XLSXS.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })
  try {
    FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), `${excelName}.xlsx`)
  } catch (e) {
    if (typeof console !== 'undefined') {
      console.log(e, wbout)
    }
  }
  return wbout
}

wb打印的结果:

 

添加样式后单元格的结构:

导出的效果:

单元格样式

设置单元格的样式,就是设置工作表对象中的单元格对象的 s 属性。这个属性的值是一个对象,它有五个属性:alignment、border、fill、font和numFmt。GitHub - gitbrent/xlsx-js-style: SheetJS Community Edition + Basic Cell Styles

猜你喜欢

转载自blog.csdn.net/weixin_55992854/article/details/126009473