xlsx-style 插件批量导出多个sheet表格excel中遇到的问题及解决
Vue2中 前端界面导出表格,使用XLSXS插件版本(^0.8.13)导出表格存在表格背景颜色无法正常展示,百分比数据没有正常展示 【有条件的尽量先升级高版本插件,此插件版本对样式支持度不够】
优先考虑插件版本升级 同样的使用方法在vue3中没有出现错误
以下为界面上表格,表格采用vxe-table组件 整个表格的列均为动态计算得出
导出后的表格样式丢失 且最后一行数据百分比不能正常展示
以下为封装的批量倒出代码 使用需根据项目自行更改
import FileSaver from 'file-saver'
import XLSXS from 'xlsx-style'export function exportMultiSheetExcel(tables, // [{ el: tableDom, name: 'Sheet1' }, ...]{fileName = '多Sheet表格',style,colWidth,callback, // 回调 对数据进行处理addCell,DataManipulationMethod}
) {const wb = XLSX.utils.book_new();tables.forEach(({ el, name, index }) => {const sheet = XLSX.utils.table_to_sheet(el);if (colWidth) sheet['!cols'] = colWidth;DataManipulationMethod && DataManipulationMethod(sheet, index);Object.keys(sheet).forEach((key) => {if (key.startsWith('!')) return;const cell = sheet[key];if (!cell || cell.v === '' || cell.v == null) return;cell.s = style || {};callback && callback(key, cell, sheet);});addCell && addCell(sheet);XLSX.utils.book_append_sheet(wb, sheet, name || 'Sheet');});const wbout = XLSXS.write(wb, {bookType: 'xlsx',type: 'binary',cellStyles: true})// 创建 Blob 并下载const blob = new Blob([s2ab(wbout)], {type: 'application/octet-stream'});const url = window.URL.createObjectURL(blob);const a = document.createElement('a');a.href = url;a.download = `${name || '表格'}.xlsx`;a.click();window.URL.revokeObjectURL(url);
}// 表格使用 ----------
import { exportMultiSheetExcel } from '@/utils'exportTable(){this.tableScheme.forEach((tableEle, index) => {// let ws = this.tableColumnHandle(tableEle.columns, this.$refs['scheme' + index][0])tables.push({el: this.$refs['scheme' + index][0].$el,// name: tableEle?.columns[0]?.title.replace(/\d{4}年/g, '').replace(/\d{2}月/g, '').replace(/:/g, '-').replace(/方案/g, ''),name: '123' + index, // sheet的名称 注意名称不能超过31个字符且不能包含:等字符index})})exportMultiSheetExcel(// 导出用隐藏的导出格式表格tables,{fileName: '方案',style: {alignment: {horizontal: 'center', // 水平居中对齐vertical: 'center',wrapText: true}},callback: (key, item, obj) => {if (key === 'B5') {console.log(key)item.s = {alignment: {horizontal: 'center', // 水平居中对齐vertical: 'center',wrapText: true},fill: {fgColor: { rgb: 'FFb0e1' }}}}},DataManipulationMethod: (data, index) => {console.log(data, 'dd')const fixedCode = ['A', 'B']const tableDataLength = this.tableScheme[index].data.length // 表格数据行数const headNum = 3 // 表头占用行数const endNum = 2 // 表尾占用行数const keysArr = []// 非A 或者 B 开始的数据 需要删除 表尾后的多余固定列脏数据 即 tableDataLength+headNum+endNum 之后的let maxNum = 0for (const key in data) {if (!key.includes('!')) {const num = key.replace(/[A-Za-z]/g, '') - 0if (num > maxNum) maxNum = numconst code = key.replace(/[0-9]/g, '')if (!keysArr.includes(code)) keysArr.push(code)if (fixedCode.includes(code) && headNum + 1 <= num && num <= tableDataLength + headNum) {if (data[key].v === '') {// 固定列替换成有数据的data[key] = data[key.replace(/[0-9]/g, '') + (num + tableDataLength + headNum + endNum)]}}}}// 删除固定列脏数据keysArr.forEach(code => {for (let num = (tableDataLength + headNum + endNum + 1); num <= maxNum; num++) {delete data[`${code + num}`]}})}})
}
插件使用过程中踩坑:
1,导出sheet名称不符规范
导出多个表格到同一个excel表格中的代码参考如下
this.tableScheme.forEach((tableEle, index) => { let ws = this.tableColumnHandle(tableEle.columns, this.$refs['scheme' + index][0]) /// 表格部分数据处理wsArr.push({title: tableEle?.columns[0]?.title, ws: ws})})const wb = XLSX.utils.book_new();wsArr.forEach( item => { // excel表格 sheet名称不能包含 :号 31个字符内const sheetName = item.title.replace(/\d{4}年/g, '').replace(/\d{2}月/g, '').replace(/:/g, '-').replace(/方案/g, '')XLSX.utils.book_append_sheet(wb, item.ws, sheetName); // 此处添加到对应的sheet中})XLSX.writeFile(wb, '调时方案执行情况.xlsx');
excel中的sheet名称要求如下:
style: {alignment: {horizontal: 'center', // 水平居中对齐vertical: 'center',wrapText: true},fill: {fgColor: { rgb: 'FFD6D6' } // 例如红色背景}
},
2,表格背景色不展示
如果设置全局的颜色 可以显示 但是对单个背景色进行设置就不显示了
全局直接在style中添加即可
style: {alignment: {horizontal: 'center', // 水平居中对齐vertical: 'center',wrapText: true},fill: {fgColor: { rgb: 'FFD6D6' } // 例如红色背景}
},
对单个背景色进行处理 在回调callback中进行条件判断 注意 必须整个item.s 一起写 包括剧中 否则就不生效
callback: (key, item, obj) => { if (key === 'B5') {item.s = {alignment: {horizontal: 'center', // 水平居中对齐vertical: 'center',wrapText: true},fill: {fgColor: { rgb: 'FFb0e1' }}}}
},
3,百分比格式设置之后不生效
正常情况只需要在回调callback中 或者 DataManipulationMethod 处理方法中对数据进行格式命名numFmt 即可
data[key].s = {alignment: { horizontal: 'center', vertical: 'center', wrapText: true },numFmt: '0.00%' // 只设置格式
}
不生效在用以下方法 直接改为string格式
const percent = data[key].v * 100;data[key].v = Number.isInteger(percent)? `${percent}%`: `${percent.toFixed(2)}%`;data[key].t = 's'; // 明确设为字符串,防止 Excel 报错