前提是安装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表格合并单元格
|