效果展示:
一、需要安装的插件 npm install file-saver -S npm install -D script-loader npm install xlsx -S (正常导出都没有问题,合并单元格,多级表头,但是不能对表格设置样式,比如背景色等等) npm install --save xlsx-style (万能,我选择这个插件,因为我需要对表格表头设置样式) 安装xlsx-style:npm install --save xlsx-style, import XLSX from "xlsx-style"报错:This relative module was not found: ./cptable in ./node_modules/xlsx-style@0.8.13@xlsx-style/dist/cpexcel.js,需要修改源码: 在 \node_modules\xlsx-style\dist\cpexcel.js找到 var cpt = require(’./cpt’ + ‘able’); 并改成 var cpt = cptable; 二、在工程目录创建一个文件夹放置Bolb.js和Export2Excel.js (1)Bolb.js /* eslint-disable / / Blob.js
- A Blob implementation.
- 2014-05-27
- By Eli Grey, http://eligrey.com
- By Devin Samarin, https://github.com/eboyjr
- License: X11/MIT
- See LICENSE.md
*/
/*global self, unescape */ /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, plusplus: true */
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
(function(view) { “use strict”;
view.URL = view.URL || view.webkitURL;
if (view.Blob && view.URL) {
try {
new Blob();
return;
} catch (e) {}
}
// Internally we use a BlobBuilder implementation to base Blob off of
// in order to support older browsers that only have BlobBuilder
var BlobBuilder =
view.BlobBuilder ||
view.WebKitBlobBuilder ||
view.MozBlobBuilder ||
(function(view) {
var get_class = function(object) {
return Object.prototype.toString
.call(object)
.match(/^\[object\s(.*)\]$/)[1];
},
FakeBlobBuilder = function BlobBuilder() {
this.data = [];
},
FakeBlob = function Blob(data, type, encoding) {
this.data = data;
this.size = data.length;
this.type = type;
this.encoding = encoding;
},
FBB_proto = FakeBlobBuilder.prototype,
FB_proto = FakeBlob.prototype,
FileReaderSync = view.FileReaderSync,
FileException = function(type) {
this.code = this[(this.name = type)];
},
file_ex_codes = (
"NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " +
"NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
).split(" "),
file_ex_code = file_ex_codes.length,
real_URL = view.URL || view.webkitURL || view,
real_create_object_URL = real_URL.createObjectURL,
real_revoke_object_URL = real_URL.revokeObjectURL,
URL = real_URL,
btoa = view.btoa,
atob = view.atob,
ArrayBuffer = view.ArrayBuffer,
Uint8Array = view.Uint8Array;
FakeBlob.fake = FB_proto.fake = true;
while (file_ex_code--) {
FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
}
if (!real_URL.createObjectURL) {
URL = view.URL = {};
}
URL.createObjectURL = function(blob) {
var type = blob.type,
data_URI_header;
if (type === null) {
type = "application/octet-stream";
}
if (blob instanceof FakeBlob) {
data_URI_header = "data:" + type;
if (blob.encoding === "base64") {
return data_URI_header + ";base64," + blob.data;
} else if (blob.encoding === "URI") {
return data_URI_header + "," + decodeURIComponent(blob.data);
}
if (btoa) {
return data_URI_header + ";base64," + btoa(blob.data);
} else {
return data_URI_header + "," + encodeURIComponent(blob.data);
}
} else if (real_create_object_URL) {
return real_create_object_URL.call(real_URL, blob);
}
};
URL.revokeObjectURL = function(object_URL) {
if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
real_revoke_object_URL.call(real_URL, object_URL);
}
};
FBB_proto.append = function(data /*, endings*/) {
var bb = this.data;
// decode data to a binary string
if (
Uint8Array &&
(data instanceof ArrayBuffer || data instanceof Uint8Array)
) {
var str = "",
buf = new Uint8Array(data),
i = 0,
buf_len = buf.length;
for (; i < buf_len; i++) {
str += String.fromCharCode(buf[i]);
}
bb.push(str);
} else if (get_class(data) === "Blob" || get_class(data) === "File") {
if (FileReaderSync) {
var fr = new FileReaderSync();
bb.push(fr.readAsBinaryString(data));
} else {
// async FileReader won't work as BlobBuilder is sync
throw new FileException("NOT_READABLE_ERR");
}
} else if (data instanceof FakeBlob) {
if (data.encoding === "base64" && atob) {
bb.push(atob(data.data));
} else if (data.encoding === "URI") {
bb.push(decodeURIComponent(data.data));
} else if (data.encoding === "raw") {
bb.push(data.data);
}
} else {
if (typeof data !== "string") {
data += ""; // convert unsupported types to strings
}
// decode UTF-16 to binary string
bb.push(unescape(encodeURIComponent(data)));
}
};
FBB_proto.getBlob = function(type) {
if (!arguments.length) {
type = null;
}
return new FakeBlob(this.data.join(""), type, "raw");
};
FBB_proto.toString = function() {
return "[object BlobBuilder]";
};
FB_proto.slice = function(start, end, type) {
var args = arguments.length;
if (args < 3) {
type = null;
}
return new FakeBlob(
this.data.slice(start, args > 1 ? end : this.data.length),
type,
this.encoding
);
};
FB_proto.toString = function() {
return "[object Blob]";
};
FB_proto.close = function() {
this.size = this.data.length = 0;
};
return FakeBlobBuilder;
})(view);
view.Blob = function Blob(blobParts, options) {
var type = options ? options.type || "" : "";
var builder = new BlobBuilder();
if (blobParts) {
for (var i = 0, len = blobParts.length; i < len; i++) {
builder.append(blobParts[i]);
}
}
return builder.getBlob(type);
};
})( (typeof self !== “undefined” && self) || (typeof window !== “undefined” && window) || this.content || this );
(2) Export2Excel.js
/* eslint-disable */ require(“script-loader!file-saver”); //保存文件用 require(“./Blob”); //转二进制用 解决浏览器报错问题 require(“script-loader!xlsx/dist/xlsx.core.min”); //xlsx核心 // import XLSX from “xlsx”; import XLSX from “xlsx-style”;
function generateArray(table) { var out = []; var rows = table.querySelectorAll(“tr”); var ranges = []; for (var R = 0; R < rows.length; ++R) { var outRow = []; var row = rows[R]; var columns = row.querySelectorAll(“td”); for (var C = 0; C < columns.length; ++C) { var cell = columns[C]; var colspan = cell.getAttribute(“colspan”); var rowspan = cell.getAttribute(“rowspan”); var cellValue = cell.innerText; if (cellValue !== “” && cellValue == +cellValue) cellValue = +cellValue;
//Skip ranges
ranges.forEach(function(range) {
if (
R >= range.s.r &&
R <= range.e.r &&
outRow.length >= range.s.c &&
outRow.length <= range.e.c
) {
for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
}
});
//Handle Row Span
if (rowspan || colspan) {
rowspan = rowspan || 1;
colspan = colspan || 1;
ranges.push({
s: { r: R, c: outRow.length },
e: { r: R + rowspan - 1, c: outRow.length + colspan - 1 }
});
}
//Handle Value
outRow.push(cellValue !== "" ? cellValue : null);
//Handle Colspan
if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
}
out.push(outRow);
}
return [out, ranges];
}
function datenum(v, date1904) { if (date1904) v += 1462; var epoch = Date.parse(v); return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000); }
function sheet_from_array_of_arrays(data, opts) { var ws = {}; var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 } }; for (var R = 0; R != data.length; ++R) { for (var C = 0; C != data[R].length; ++C) { if (range.s.r > R) range.s.r = R; if (range.s.c > C) range.s.c = C; if (range.e.r < R) range.e.r = R; if (range.e.c < C) range.e.c = C; var cell = { v: data[R][C] }; // 修改点1:如果单元格所在的值为空,让其值为’–',否则下面设置的边框对其不生效 // if (cell.v == null) continue; if (cell.v == null) { cell.v = ‘–’ } var cell_ref = XLSX.utils.encode_cell({ c: C, r: R });
if (typeof cell.v === "number") cell.t = "n";
else if (typeof cell.v === "boolean") cell.t = "b";
else if (cell.v instanceof Date) {
cell.t = "n";
cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
} else cell.t = "s";
ws[cell_ref] = cell;
}
}
if (range.s.c < 10000000) ws["!ref"] = XLSX.utils.encode_range(range);
return ws;
}
function Workbook() { if (!(this instanceof Workbook)) return new Workbook(); this.SheetNames = []; this.Sheets = {}; }
function s2ab(s) { var buf = new ArrayBuffer(s.length); var view = new Uint8Array(buf); for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff; return buf; }
export function export_table_to_excel(id) { var theTable = document.getElementById(id); var oo = generateArray(theTable); var ranges = oo[1];
/* original data */
var data = oo[0];
var ws_name = "SheetJS";
var wb = new Workbook(),
ws = sheet_from_array_of_arrays(data);
/* add ranges to worksheet */
// ws['!cols'] = ['apple', 'banan'];
ws["!merges"] = ranges;
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: false,
type: "binary"
});
saveAs(
new Blob([s2ab(wbout)], { type: "application/octet-stream" }),
"test.xlsx"
);
}
export function export_json_to_excel({ header, data, filename = “excel-list”,//文件名称不传就是默认的 autoWidth = true, stateMentType = ‘’, merges = [],//需要合并的表格 multiHeader = [],//多级表头 tableTitle = [],//报表的第一行名字 tableScendSubTitle = [],//报表的第二行名字, tableEmpty = [],//与初始化表格中间的空的间隔 monthEmpty = [] } = {}) { /* original data */ let monthLength = 31 //表格的数据内容 data = […data]; //表格下面需要展示二级标题 只有年和月才有的二级标题 if(stateMentType) { if(stateMentType == ‘month’ || stateMentType == ‘year’){ data.unshift(monthEmpty) } } //表格的文字标题 data.unshift(header);
//处理多级表头
//根据stateMentType 判断是导出日报表还是月报表还是年报表还是默认报表
console.log(stateMentType)
for (let i = multiHeader.length - 1; i > -1; i--) {
data.unshift(multiHeader[i]);
}
if(stateMentType) {
//表格子标题
data.unshift(tableScendSubTitle)
//表格标题
data.unshift(tableTitle)
}
var ws_name = "Sheet1";
var wb = new Workbook(),
ws = sheet_from_array_of_arrays(data);
//单元格合并
if (merges.length > 0) {
if (!ws['!merges']) ws['!merges'] = [];
merges.forEach(item => {
ws['!merges'].push(XLSX.utils.decode_range(item))
})
}
if (autoWidth) {
/*设置worksheet每列的最大宽度*/
const colWidth = data.map(row =>
row.map(val => {
/*先判断是否为null/undefined*/
if (val == null) {
return { wch: 10 };
} else if (val.toString().charCodeAt(0) > 255) {
/*再判断是否为中文*/
return { wch: val.toString().length * 2 };
} else {
return { wch: val.toString().length * 1.5 };
}
})
);
/*以第一行为初始值*/
//根据stateMentType判断是从第几行开始为初始行
let result = null
switch (stateMentType) {
case 'total':
result = colWidth[3]
break;
case 'month':
result = colWidth[3]
break
case 'year':
result = colWidth[3]
break
default:
result = colWidth[0]
}
for (let i = 1; i < colWidth.length; i++) {
for (let j = 0; j < colWidth[i].length; j++) {
if (result[j]["wch"] < colWidth[i][j]["wch"]) {
result[j]["wch"] = colWidth[i][j]["wch"];
}
}
}
ws["!cols"] = result;
}
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
if(stateMentType) {
//设置单元格样式
//获取sheet1中数据循环所有有内容的表格进行格式设置
let dataInfo = wb.Sheets[wb.SheetNames[0]];
// 设置单元格框线
const borderAll = {
top: {
style: "thin"
},
bottom: {
style: "thin"
},
left: {
style: "thin"
},
right: {
style: "thin"
}
};
// 给所有单元格加上边框,内容居中,字体,字号,标题表头特殊格式部分后面替换
for (var i in dataInfo) {
if (
i == "!ref" ||
i == "!merges" ||
i == "!cols" ||
i == "!rows" ||
i == "A1"
) {
} else {
dataInfo[i + ""].s = {
border: borderAll,
alignment: {
horizontal: "center",
vertical: "center"
},
font: {
name: "微软雅黑",
sz: 10
}
};
}
}
// 去掉标题边框
let arr = ["A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1", "I1", "J1", "K1","L1"];
arr.forEach(v => {
if(dataInfo[v]){
dataInfo[v].s = {}
}
})
let subArr = ["A2", "B2", "C2", "D2", "E2", "F2", "G2", "H2", "I2", "J2", "K2","L2"];
subArr.forEach(v => {
if(dataInfo[v]){
dataInfo[v].s = {}
}
})
//设置主标题样式
dataInfo["A1"].s = {
border: {},
font: {
name: '微软雅黑',
sz: 14,
// color: {rgb: "ff0000"},
bold: true,
italic: false,
underline: false
},
alignment: {
horizontal: "center",
vertical: "center"
},
// fill: {
// fgColor: {rgb: "008000"},
// },
};
//设置副标题样式
dataInfo["A2"].s = {
border: {},
font: {
name: '微软雅黑',
sz: 10,
// color: {rgb: "ff0000"},
bold: false,
italic: false,
underline: false
},
alignment: {
horizontal: "center",
vertical: "center"
},
// fill: {
// fgColor: {rgb: "008000"},
// },
};
//设置标题的样式
let titleArray = [];
if(stateMentType == 'month') {
titleArray = ["A3", "B3", "C3", "D3", "E3", "F3", "G3", "H3","A4", "B4", "C4", "D4", "E4", "F4", "G4", "H4","I3","I4","J3","J4","K3","K4","L3","L4"]
}else if(stateMentType == 'year') {
titleArray = ["A3", "B3", "C3", "D3", "E3", "F3", "G3", "H3","A4", "B4", "C4", "D4", "E4", "F4", "G4", "H4","I3","I4","J3","J4","K3","K4","L3","L4"]
}else {
//total的要根据年的个数来动态获取 2020 2021
titleArray = ["A3", "B3", "C3", "D3", "E3", "F3", "G3", "H3","I3","J3","K3","L3","M3","N3","O3","P3","Q3","R3","S3","T3","U3"]
}
titleArray.forEach(item => {
dataInfo[item].s = {
border: borderAll,
font: {
name: '微软雅黑',
sz: 12,
// color: {rgb: "ff0000"},
bold: true,
italic: false,
underline: false
},
alignment: {
horizontal: "center",
vertical: "center"
},
fill: {
fgColor: stateMentType == 'total' ? {rgb: "F79B3F"} : {rgb: "92D050"},
},
};
})
//设置二级标题的样式
let subTitleArray = []
if(stateMentType == 'month') {
if(monthLength == 28){
subTitleArray = ["L4", "M4", "N4", "O4", "P4", "Q4","R4", "S4", "T4", "U4", "V4", "W4", "X4", "Y4","Z4","AA4","AB4","AC4","AD4","AE4","AF4","AG4","AH4","AI4","AJ4","AK4","AL4","AM4"]
}else if(monthLength == 29) {
subTitleArray = ["L4", "M4", "N4", "O4", "P4", "Q4","R4", "S4", "T4", "U4", "V4", "W4", "X4", "Y4","Z4","AA4","AB4","AC4","AD4","AE4","AF4","AG4","AH4","AI4","AJ4","AK4","AL4","AM4","AN4"]
}else if(monthLength == 30) {
subTitleArray = ["L4", "M4", "N4", "O4", "P4", "Q4","R4", "S4", "T4", "U4", "V4", "W4", "X4", "Y4","Z4","AA4","AB4","AC4","AD4","AE4","AF4","AG4","AH4","AI4","AJ4","AK4","AL4","AM4","AN4","AO4"]
}else{
subTitleArray = ["L4", "M4", "N4", "O4", "P4", "Q4","R4", "S4", "T4", "U4", "V4", "W4", "X4", "Y4","Z4","AA4","AB4","AC4","AD4","AE4","AF4","AG4","AH4","AI4","AJ4","AK4","AL4","AM4","AN4","AO4","AP4"]
}
}else if(stateMentType == 'year'){
subTitleArray = ["L4", "M4", "N4", "O4", "P4", "Q4","R4", "S4", "T4", "U4", "V4", "W4"]
}
//累积没有二级标题
subTitleArray.forEach(item => {
dataInfo[item].s = {
border: borderAll,
font: {
name: '微软雅黑',
sz: 10,
// color: {rgb: "ff0000"},
bold: false,
italic: false,
underline: false
},
alignment: {
horizontal: "center",
vertical: "center"
},
fill: {
fgColor: {rgb: "FFC000"},
},
};
})
if(stateMentType == 'total') {
const totalContentArray = ['A4','B4','C4','D4','E4','F4','G4','H4','I4','J4','K4','L4']
totalContentArray.forEach(item =>{
dataInfo[item].s = {
border: borderAll,
font: {
name: '微软雅黑',
sz: 10,
// color: {rgb: "ff0000"},
bold: false,
italic: false,
underline: false
},
alignment: {
horizontal: "center",
vertical: "center"
},
// fill: {
// fgColor: {rgb: "FFC000"},
// },
}
})
}
}
var wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: false,
type: "binary"
});
saveAs(
new Blob([s2ab(wbout)], { type: "application/octet-stream" }),
filename + ".xlsx"
);
}
三、export_json_to_excel方法调用(部分代码与业务逻辑有关,可以忽略,但是最终的结果就是如下) 结果呈现:
//前端实现导出excel exportData(rowData,exportMulFlag) { let THAT = this; //根据报表类型设置不同的报表标题 let header = [] let filterVal = [] if(exportMulFlag != undefined){ THAT.mulDownloading = true } let list = exportMulFlag == undefined ? [rowData] : rowData; let merges = [] let monthEmpty = [] let tableTitle = [] let tableCreateTime = “报表数据截止时间” + dayjs().format(‘YYYY-MM-DD’) + " 00:00:00" let tableScendSubTitle = [] if(THAT.changeDateType == ‘month’) { header = [‘电站名称’,‘时间’,‘国家’,‘省份或区域’,‘城市’,‘电站地址’,‘业主’,‘月等效利用小时数’,‘月发电量(kWh)’,‘月二氧化碳排量(kg)’,‘月收益’,‘累积发电量(kWh)’,‘数据类型’] filterVal = [ ‘powerName’, ‘time’,‘country’, ‘province’, ‘city’, ‘address’, ‘owner’, ‘equivalentHours’,‘generationTimeTotal’,‘dischargeCo2’,‘earningTimeTotal’,‘generationTotal’,‘dataType’]; let currentMonth = String((new Date()).getMonth() + 1) header.push(‘日期’) monthEmpty = [‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘’] for(let i = 0;i <THAT.monthLength;i++) { filterVal.push(‘day’ + (i+1)) if(i<THAT.monthLength-1){ header.push(“”) } monthEmpty.push(String(i+1)) } if(THAT.monthLength == 28){ merges = [ “A1:M1”, “A2:M2”, “A3:A4”, “B3:B4”, “C3:C4”, “D3:D4”, “E3:E4”, “F3:F4”, “G3:G4”, “H3:H4”, “I3:I4”, “J3:J4”, “K3:K4”, “L3:L4”, “M3:M4”, “N3:AO3” ] }else if(THAT.monthLength == 29) { merges = [ “A1:M1”, “A2:M2”, “A3:A4”, “B3:B4”, “C3:C4”, “D3:D4”, “E3:E4”, “F3:F4”, “G3:G4”, “H3:H4”, “I3:I4”, “J3:J4”, “K3:K4”, “L3:L4”, “M3:M4”, “N3:AP3” ] }else if(THAT.monthLength == 30) { merges = [ “A1:M1”, “A2:M2”, “A3:A4”, “B3:B4”, “C3:C4”, “D3:D4”, “E3:E4”, “F3:F4”, “G3:G4”, “H3:H4”, “I3:I4”, “J3:J4”, “K3:K4”, “L3:L4”, “M3:M4”, “N3:AQ3” ] }else{ merges = [ “A1:M1”, “A2:M2”, “A3:A4”, “B3:B4”, “C3:C4”, “D3:D4”, “E3:E4”, “F3:F4”, “G3:G4”, “H3:H4”, “I3:I4”, “J3:J4”, “K3:K4”, “L3:L4”, “M3:M4”, “N3:AR3”, ] } tableTitle = [‘光伏电站发电量报表(月报)’,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”] tableScendSubTitle = [tableCreateTime,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”] }else if(THAT.changeDateType == ‘year’){ header = [‘电站名称’,‘时间’,‘国家’,‘省份或区域’,‘城市’,‘电站地址’,‘业主’,‘年等效利用小时数’,‘年发电量(kWh)’,‘年二氧化碳减排量(kg)’,‘年收益’,‘累积发电量(kWh)’,‘数据类型’] filterVal = [‘powerName’,‘time’, ‘country’, ‘province’, ‘city’, ‘address’, ‘owner’, ‘equivalentHours’,‘generationTimeTotal’,‘dischargeCo2’,‘earningTimeTotal’,‘generationTotal’,‘dataType’]; monthEmpty = [‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘’] // let currentYear = String((new Date()).getFullYear()) header.push(‘月份’) for(let i = 0;i <12;i++) { filterVal.push(‘month’ + (i+1)) if(i<11){ header.push(“”) } monthEmpty.push(String(i+1)) } merges = [ “A1:M1”, “A2:M2”, “A3:A4”, “B3:B4”, “C3:C4”, “D3:D4”, “E3:E4”, “F3:F4”, “G3:G4”, “H3:H4”, “I3:I4”, “J3:J4”, “K3:K4”, “L3:L4”, “M3:M4”, “N3:Y3” ] tableTitle = [‘光伏电站发电量报表(年报)’,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”] tableScendSubTitle = [tableCreateTime,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”] }else{ header = [‘电站名称’,‘时间’,‘国家’,‘省份或区域’,‘城市’,‘电站地址’,‘业主’,‘累积等效利用小时数’,‘累积收益’,‘累积发电量(kWh)’,‘累积二氧化碳减排量(kg)’,‘数据类型’,‘2020’,‘2021’,‘2022’,‘2023’,‘2024’,‘2025’,‘2026’,‘2027’,‘2028’,‘2029’,‘2030’] filterVal = [ ‘powerName’,‘time’, ‘country’, ‘province’, ‘city’, ‘address’, ‘owner’, ‘equivalentHours’,‘earningTimeTotal’,‘generationTotal’,‘dischargeCo2’,‘dataType’,‘year2020’,‘year2021’,‘year2022’,‘year2023’,‘year2024’,‘year2025’,‘year2026’,‘year2027’,‘year2028’,‘year2029’,‘year2030’]; tableTitle = [‘光伏电站发电量报表(累积)’,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”] tableScendSubTitle = [tableCreateTime,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”,“”] merges = [ “A1:J1”, “A2:J2”, ] } if(list.length == 0) { this.KaTeX parse error: Expected 'EOF', got '}' at position 57: …return }? //根据数据…{i+4+i5}:A
i
+
4
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
B
{i+4+i*5+middleNumber}`, `B
i+4+i?5+middleNumber‘,‘B{i+4+i5}:B
i
+
4
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
C
{i+4+i*5+middleNumber}`, `C
i+4+i?5+middleNumber‘,‘C{i+4+i5}:C
i
+
4
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
D
{i+4+i*5+middleNumber}`, `D
i+4+i?5+middleNumber‘,‘D{i+4+i5}😄
i
+
4
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
E
{i+4+i*5+middleNumber}`, `E
i+4+i?5+middleNumber‘,‘E{i+4+i5}:E
i
+
4
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
F
{i+4+i*5+middleNumber}`, `F
i+4+i?5+middleNumber‘,‘F{i+4+i5}:F
i
+
4
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
G
{i+4+i*5+middleNumber}`, `G
i+4+i?5+middleNumber‘,‘G{i+4+i5}:G
i
+
4
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
H
{i+4+i*5+middleNumber}`, `H
i+4+i?5+middleNumber‘,‘H{i+4+i5}:H
i
+
4
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
I
{i+4+i*5+middleNumber}`, `I
i+4+i?5+middleNumber‘,‘I{i+4+i5}:I
i
+
4
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
J
{i+4+i*5+middleNumber}`, `J
i+4+i?5+middleNumber‘,‘J{i+4+i5}:J
i
+
4
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
K
{i+4+i*5+middleNumber}`, `K
i+4+i?5+middleNumber‘,‘K{i+4+i5}:KKaTeX parse error: Expected 'EOF', got '}' at position 56: …] }?else{ …{i+5+i5}:A
i
+
5
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
B
{i+5+i*5+middleNumber}`, `B
i+5+i?5+middleNumber‘,‘B{i+5+i5}:B
i
+
5
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
C
{i+5+i*5+middleNumber}`, `C
i+5+i?5+middleNumber‘,‘C{i+5+i5}:C
i
+
5
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
D
{i+5+i*5+middleNumber}`, `D
i+5+i?5+middleNumber‘,‘D{i+5+i5}😄
i
+
5
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
E
{i+5+i*5+middleNumber}`, `E
i+5+i?5+middleNumber‘,‘E{i+5+i5}:E
i
+
5
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
F
{i+5+i*5+middleNumber}`, `F
i+5+i?5+middleNumber‘,‘F{i+5+i5}:F
i
+
5
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
G
{i+5+i*5+middleNumber}`, `G
i+5+i?5+middleNumber‘,‘G{i+5+i5}:G
i
+
5
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
H
{i+5+i*5+middleNumber}`, `H
i+5+i?5+middleNumber‘,‘H{i+5+i5}:H
i
+
5
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
I
{i+5+i*5+middleNumber}`, `I
i+5+i?5+middleNumber‘,‘I{i+5+i5}:I
i
+
5
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
J
{i+5+i*5+middleNumber}`, `J
i+5+i?5+middleNumber‘,‘J{i+5+i5}:J
i
+
5
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
K
{i+5+i*5+middleNumber}`, `K
i+5+i?5+middleNumber‘,‘K{i+5+i5}:K
i
+
5
+
i
?
5
+
m
i
d
d
l
e
N
u
m
b
e
r
‘
,
‘
L
{i+5+i*5+middleNumber}`, `L
i+5+i?5+middleNumber‘,‘L{i+5+i5}:L${i+5+i5+middleNumber}` ] } merges = merges.concat(array) } let data = THAT.formatJson(filterVal,list); let filename = ‘’ if(THAT.changeDateType == ‘month’) { filename = ‘月报表’ + dayjs().format(‘YYYY-MM-DD HH:mm:ss’); }else if(THAT.changeDateType == ‘year’){ filename = ‘年报表’ + dayjs().format(‘YYYY-MM-DD HH:mm:ss’); }else{ filename = ‘累积报表’ + dayjs().format(‘YYYY-MM-DD HH:mm:ss’); } let autoWidth = true let stateMentType = THAT.changeDateType let multiHeader = [] let tableEmpty = [“”,“”,“”,“”,“”,“”,“”,“”,“”] export_json_to_excel({header,data,filename,autoWidth,stateMentType,merges,multiHeader,tableTitle,tableScendSubTitle,tableEmpty,monthEmpty})
//执行图片下载的方法
if(THAT.realTimeChartFlag){
const elink = document.createElement('a');
elink.download = THAT.downLoadEchartTitle;
elink.style.display = 'none';
elink.href = THAT.realTimeChartBase64Url;
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href); // 释放URL 对象
document.body.removeChild(elink)
}
THAT.mulDownloading = false
}
四、相关注意事项 (1) merges的设置根据自己表格情况自己设定,合并的顺序就是从左往右的方式 (2) 多级表格的实现有在自己开发过程中使用两种方式 a、使用multiHeader配合merges完成多级表头的实现
b、也可以使用与header长度一致的数据当值在data前面,配合merges实现多级表头
|