前期准备
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