前提是安装xlsx,已经可以导出普通的excel
npm install --save xlsx file-saver
然后需要安装
npm install xlsx-style
如果运行的时候报错
需要修改源码,然后重新运行:
1、在\node_modules\xlsx-style\dist\cpexcel.js 807行把 var cpt = require('./cpt' + 'able');
改成 var cpt = cptable;
2、在\node_modules\xlsx-style\ods.js 10行和13行把路径改为 require('./xlsx')
Blob.js 和Export2Excel.js 网上有很多
我在Export2Excel中做了修改,代码如下:
//Export2Excel.js
require('script-loader!file-saver');
require('./Blob.js');//这里是你的Blob.js的地址
require('script-loader!xlsx/dist/xlsx.core.min');
import XLSXS from "xlsx-style"必须要引入才可以,否则报错
export function export_json_to_excelhb({
multiHeader2 = [], // 第一行表头
multiHeader = [], // 第二行表头
header, // 第三行表头
data,//传递的数据
filename, //文件名
merges = [], // 合并
autoWidth = true,//用于设置列宽的
bookType = 'xlsx'
} = {}) {
/* original data */
filename = filename || '列表';
data = [...data]
data.unshift(header);
for (let i = multiHeader2.length - 1; i > -1; i--) {
data.unshift(multiHeader2[i])
}
for (let i = multiHeader.length - 1; i > -1; i--) {
data.unshift(multiHeader[i])
}
var ws_name = "SheetJS";
var wb = new Workbook(),
ws = sheet_from_array_of_arrays(data);
let borderAll = { //单元格外侧框线
top: {
style: 'medium',
},
bottom: {
style: 'medium'
},
left: {
style: 'medium'
},
right: {
style: 'medium'
}
};
for (let key in ws) {
if (ws[key] instanceof Object) {
ws[key].s = {
border: borderAll,
alignment: {
horizontal: 'center', //水平居中对齐
vertical: 'center',//垂直居中
wrapText: 1,//自动换行
},
font: {
sz: 10,//单元格中字体的样式与颜色设置
color: {
rgb: '495060'
}
},
bold: true,
numFmt: 0
}
}
}
ws['I2'] = ws['H2'] = ws['G2'] = ws['F2'] = ws['E2'] = ws['D2'] = ws['C2'] = ws['B2'] = ws['A2']//用于第二行的单元格的样式设置(如果是合并的第一行,就是1)
if (merges.length > 0) {
if (!ws['!merges']) ws['!merges'] = [];
merges.forEach(item => {
ws['!merges'].push(XLSX.utils.decode_range(item))
})
}
if (autoWidth) {
let colWidths = [];
// 计算每一列的所有单元格宽度
// 先遍历行
data.forEach((row) => {
// 列序号
let index = 0
// 遍历列
for (const key in row) {
if (colWidths[index] == null) colWidths[index] = []
switch (typeof row[key]) {
case 'string':
case 'number':
case 'boolean': colWidths[index].push(getCellWidth(row[key]))
break
case 'object':
case 'function':
colWidths[index].push(0)
break
}
index++
}
})
ws['!cols'] = [];
colWidths.forEach((widths, index) => {
// 计算列头的宽度
widths.push(getCellWidth(header[index]))
// 设置最大值为列宽
ws['!cols'].push({
wch: Math.max(...widths)
})
})
}
console.log(ws);
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSXS.write(wb, {
bookType: bookType,
bookSST: false,
type: 'binary'
});
saveAs(new Blob([s2ab(wbout)], {
type: "application/octet-stream"
}), `${filename}.${bookType}`);
}
export function getCellWidth(value) {
if (value == null) {
return 10
} else if (value.toString().charCodeAt(0) > 255) {
// 判断是否包含中文
let length = value.toString().length * 2
if (length > 60) {
length = length - 40
//这里的宽度可以自己设定,在前面设置wrapText: 1可以在单元格内换行
}
return length
} else {
return value.toString().length * 1.2
}
}
在自己的文件中调用
数据的格式,比如:
data=[{mc:"aaa",sex:'女'},{mc:"bbb",sex:'男'}]
tHeader=["名称","性别"]
filterVal=["mc","sex"]
handleExportexcel() {
//@/excel/Export2Excel是自己的Export2Excel的文件的地址
import("@/excel/Export2Excel").then((excel) => {
const multiHeader = [["光缆熔接纤序表"]];
const multiHeader2 = [["设备名称"];
const tHeader = [];
const filterVal = []; // 表头所对应的字段,这里未填写,请自行填写对应的字段,按实际需求请自行处理该步
let data = rjdata.map((v) => filterVal.map((j) => v[j])); //rjdata为请求的数据,此处理是为了对应字段,如不需要此处理,直接为data赋值即可
// 进行所有表头的单元格合并
let merges = [
"A1:I1",
"A2:I2", //合并行
"A4:A6",
"B4:B6",
];//如果是A1到I1合并就写A1:I1
let excelname = String(
new Date().format("yyyy-MM-dd-HH-mm-ss")
).replace(/[^0-9]/gi, "");//导出的excel的名字
excel.export_json_to_excelhb({
multiHeader, // 这里是第一行的表头
multiHeader2, // 这里是第二行的表头
header: tHeader, // 这里是第三行的表头
data,
filename: excelname,
merges,
});
});
},
},
最终的实现结果如下图
参考了下面两个大佬的文章,我的需求比他们的复杂一点。
参考链接:JavaScript导出excel文件,并修改文件样式_FEWY的博客-CSDN博客_js导出excel设置样式
Vue 前端导出Excel表格,多级表头合并_迈向前端攻城狮的路上-CSDN博客_vue导出excel表格合并单元格
xlsx-style ./cptable' 报错解决办法 - 龙果果 - 博客园