前端使用xlsx file-saver xlsx-style导出
import FileSaver from 'file-saver'
import XLSXStyle from "xlsx-style";
import XLSX from 'xlsx'
vue 2.0版本xlsx-style ./cptable' 报错:Can't resolve './cptable' in 'xxxx\nautical-front\node_modules_xlsx
解决办法
1根据脚手架版本不同可以在 webpack.base.conf.js 中写
module.exports = {
externals: [ {
'./cptable': 'var cptable'
}]
}
也可以在vue.config.js中写
module.exports = {
chainWebpack: config => {
config.externals({ './cptable': 'var cptable' })
}
}
问题所在:\node_modules\xlsx-style\dist\cpexcel.js 807行 var cpt = require('./cpt' + 'able');
修改为 var cpt = cptable 修改的只是本地文件
不推荐这种方式,因为你只是修改了自己的本地文件呢,下一次其他人进行打包或运行项目一样会报这类错误
setExlStyle(data) {
let borderAll = { //单元格外侧框线
// top: {
// style: 'thin',
// },
// bottom: {
// style: 'thin'
// },
// left: {
// style: 'thin'
// },
// right: {
// style: 'thin'
// }
};
data['!cols'] = [];
for (let key in data) {
// console.log(key)
if (data[key] instanceof Object) {
data[key].s = {
border: borderAll,
alignment: {
horizontal: 'center', //水平居中对齐
vertical:'center'
},
font:{
sz:11
},
bold:true,
numFmt: 0
}
data['!cols'].push({wpx: 160});
}
}
return data;
},
addRangeBorder (range, ws) {
console.log(range)
let cols = ["A", "B", "C", "D", "E"];
range.forEach(item => {
console.log(item)
let style = {
// s: {
// border: {
// top: { style: 'thin' },
// left: { style: 'thin' },
// bottom: { style: 'thin' },
// right: { style: 'thin' }
// }
// }
}
// 处理合并行
for (let i = item.s.c; i <= item.e.c; i++) {
ws[`${cols[i]}${Number(item.e.r) + 1}`] = ws[`${cols[i]}${Number(item.e.r) + 1}`] || style
// 处理合并列
for (let k = item.s.r + 2; k <= item.e.r + 1; k++) {
ws[cols[i] + k] = ws[cols[k] + item.e.r] || style
}
}
})
return ws;
},
exportExcel(){
let ws = XLSX.utils.table_to_sheet(this.$refs['report-table'].$el)
//创建一个workbook对象
let wb = XLSX.utils.book_new()
//把worksheet对象添加进workbook对象,第三个参数是excel中sheet的名字
XLSX.utils.book_append_sheet(wb, ws, '列表')
this.setExlStyle(wb['Sheets']['列表']); // 设置列宽 字号等 如果无需多余的样式则省略
this.addRangeBorder(wb['Sheets']['列表']['!merges'],wb['Sheets']['列表']) //设置合并行的border
let wb_out = XLSXStyle.write(wb, { type: 'buffer'})
try {
FileSaver.saveAs(new Blob([wb_out], {
type: 'application/octet-stream'
}), '用时用工统计表.xlsx'); // 导出的文件名
} catch (e) {
console.log(e, wb_out) ;
}
return wb_out;
},
rowspan(spanArr, position, spanName) {
this.list.forEach((item, index) => {
if (index === 0) {
spanArr.push(1);
position = 0;
} else {
if (
this.list[index][spanName] ===
this.list[index - 1][spanName]
) {
spanArr[position] += 1;
spanArr.push(0);
} else {
spanArr.push(1);
position = index;
}
}
});
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
const _row = this.testArr0[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col,
};
}
if (columnIndex === 1) {
const _row = this.testArr1[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col,
};
}
if (columnIndex === 2) {
const _row = this.testArr2[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col,
};
}
if (columnIndex ===3) {
const _row = this.testArr3[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col,
};
}
},
this.rowspan(this.testArr3, this.testPosition3, "num");
对应的表格
<el-table :data="list" fit border stripe
highlight-current-row
ref="report-table"
:span-method="objectSpanMethod"
@selection-change="handleSelectionChange"
height="100%">

对应导出列表
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构