效果展示:
一、需要安装的插件
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实现多级表头