import { saveAs } from "file-saver";
import XLSX from "yxg-xlsx-style";
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]
};
if (cell.v == null) continue;
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;
}
/*
导出excl
style字段说明
style-coordinate:位置(A1)
style-fgColor:背景颜色ARGB(ff0f0f0f)
style-horizontal:水平排列("bottom"||"center"||"top")
style-fontSZ:字体大小("11")
style-fontBold:是否加粗(`true || false`)
style-color:字体颜色ARGB(ff0f0f0f)
merges:合并单元格参数
{
s: {//s为开始
c: 1,//开始列
r: 0//可以看成开始行,实际是取值范围
},
e: {//e结束
c: 4,//结束列
r: 0//结束行
}
}
*/
export function export_json_to_excel({
multiHeader = [],
style = [],
header,
data,
filename,
merges = [],
autoWidth = true,
bookType = "xlsx",
sheetName = "SheetJS"
} = {}){
/* original data */
filename = filename || "excel-list";
data = [...data];
data.unshift(header);
for (let i = multiHeader.length - 1; i > -1; i--) {
data.unshift(multiHeader[i]);
}
let wb = new Workbook();
let ws = sheet_from_array_of_arrays(data);
if (merges.length > 0) {
if (!ws["!merges"]) ws["!merges"] = [];
merges.forEach(item => {
ws["!merges"].push(item);
});
}
//设置单元格格式
if (style.length > 0) {
style.forEach(item => {
if (ws[item.coordinate]) {
ws[item.coordinate].s = {
fill: { fgColor: item.fgColor ? { rgb: item.fgColor } : { auto: 1 } },
alignment: { horizontal: item.horizontal ? item.horizontal : "bottom" },
font: {
sz: item.fontSZ ? item.fontSZ : "11",
bold: item.fontBold ? item.fontBold : "false",
color: item.color ? { rgb: item.color } : { auto: 1 }
}
};
}
});
}
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
};
}
})
);
/*以第一行为初始值*/
let 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(sheetName);
wb.Sheets[sheetName] = ws;
var wbout = XLSX.write(wb, {
bookType: bookType,
bookSST: false,
type: "binary"
});
saveAs(
new Blob([s2ab(wbout)], {
type: "application/octet-stream"
}),
`${filename}.${bookType}`
);
}
/*
sheet字段说明
sheet-data:数据
sheet-header:头
sheet-multiHeader:多级头
sheet-merges:合并单元格参数,参考export_json_to_excel
sheet-style:单元格样式参数,参考export_json_to_excel
sheet-autoWidth:是否自动宽度
sheet-sheetName:表名
*/
export function export_json_to_excel_batch({
sheet,
filename,
bookType = "xlsx"
} = {}){
/* original data */
filename = filename || "excel-list";
let wb = new Workbook();
for (let j = 0; j < sheet.length; j++) {
let data = [...sheet[j].data];
data.unshift(sheet[j].header);
if (sheet[j].multiHeader) {
for (let i = sheet[j].multiHeader.length - 1; i > -1; i--) {
data.unshift(sheet[j].multiHeader[i]);
}
}
let ws = sheet_from_array_of_arrays(data);
//处理单元格合并
if (sheet[j].merges) {
if (sheet[j].merges.length > 0) {
if (!ws["!merges"]) ws["!merges"] = [];
sheet[j].merges.forEach(item => {
ws["!merges"].push(item);
});
}
}
//设置单元格格式
if (sheet[j].style.length > 0) {
sheet[j].style.forEach(item => {
if (ws[item.coordinate]) {
ws[item.coordinate].s = {
fill: { fgColor: item.fgColor ? { rgb: item.fgColor } : {} },
alignment: {
horizontal: item.horizontal ? item.horizontal : "bottom"
},
font: {
sz: item.fontSZ ? item.fontSZ : "11",
bold: item.fontBold ? item.fontBold : "false",
color: item.color ? { rgb: item.color } : { auto: 1 }
}
};
if (!item.fgColor) {
delete ws[item.coordinate].s.fill
}
}
});
}
if (!sheet[j].autoWidth) {
sheet[j].autoWidth = true;
}
if (sheet[j].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
};
}
})
);
/*以第一行为初始值*/
let 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(sheet[j].sheetName);
wb.Sheets[sheet[j].sheetName] = ws;
}
var wbout = XLSX.write(wb, {
bookType: bookType,
bookSST: false,
type: "binary"
});
saveAs(
new Blob([s2ab(wbout)], {
type: "application/octet-stream"
}),
`${filename}.${bookType}`
);
}