import dayjs from "dayjs";
import * as XLSX from "xlsx";
import XLSXS from "xlsx-style";
export function export2Excel(info: {
title: string;
data: any[] | Record<string, any>[];
header: {
title: any;
key: any;
}[];
}) {
const { title, data, header } = info;
const tableTitle = `${title}_评论数据_${dayjs().format(
"YYYY-MM-DD_HH_mm_ss"
)}`;
const wb = XLSX.utils.book_new();
addSheet({
xl: XLSX,
wb,
data,
header,
tableTitle,
});
const tmpDown = new Blob([
s2ab(
XLSXS.write(wb, {
bookType: "xlsx",
type: "binary",
})
) as any,
]);
downExcel(tmpDown, tableTitle + ".xlsx");
}
const addSheet = (info: {
wb: any;
xl: any;
data: any[] | Record<string, any>[];
header: {
title: any;
key: any;
}[];
tableTitle: string;
}) => {
const { wb, xl, data, header, tableTitle } = info;
const keyArr = header.map((item: any) => item.key);
const nameArr = header.map((item: any) => item.title);
const excelData = [nameArr];
data.forEach((item: any) => {
const dataArr: any = [];
keyArr.forEach((key: any) => {
dataArr.push(item[key]);
});
excelData.push(dataArr);
});
const tableData = xl.utils.aoa_to_sheet(excelData);
tableData["!cols"] = [];
tableData["!rows"] = [{ hpx: 40 }, { hpx: 40 }, { hpx: 40 }];
header.forEach((col: any, colIndex: any) => {
switch (col.key) {
case "commentTime":
tableData["!cols"].push({ wch: 18 });
break;
case "connect":
tableData["!cols"].push({ wch: 25 });
break;
default:
tableData["!cols"].push({ wch: 15 });
break;
}
excelData.forEach((row, rowIndex) => {
const cellPosition = createPosition(colIndex, rowIndex);
if (tableData[cellPosition]) {
tableData[cellPosition].s = {
alignment: {
horizontal: "left",
vertical: "center",
},
fill: {
},
border: {
top: { style: "thin", color: { rgb: "ebebeb" } },
bottom: { style: "thin", color: { rgb: "ebebeb" } },
left: { style: "thin", color: { rgb: "ebebeb" } },
right: { style: "thin", color: { rgb: "ebebeb" } },
},
};
if (rowIndex === 0) {
tableData[cellPosition].s.fill = {
};
tableData[cellPosition].s.font = {
sz: "12",
bold: true,
shadow: true,
};
} else if (
typeof row[colIndex] === "string" &&
row[colIndex].includes("%")
) {
let value = tableData[cellPosition].v;
value = Number(value.replace("%", ""));
tableData[cellPosition].v = (value / 100).toFixed(4);
tableData[cellPosition].z = XLSX.SSF._table[10];
tableData[cellPosition].t = "n";
}
}
});
});
xl.utils.book_append_sheet(wb, tableData, tableTitle.substring(0, 31));
};
const downExcel = (obj: any, fileName: string) => {
const a_node = document.createElement("a");
a_node.download = fileName;
if ("msSaveOrOpenBlob" in navigator) {
(navigator as any).msSaveOrOpenBlob(obj, fileName);
} else {
a_node.href = URL.createObjectURL(obj);
}
a_node.click();
setTimeout(() => {
URL.revokeObjectURL(obj);
}, 2000);
};
const s2ab = (s: any) => {
if (typeof ArrayBuffer !== "undefined") {
const buf = new ArrayBuffer(s.length);
const view = new Uint8Array(buf);
for (let i = 0; i != s.length; ++i) {
view[i] = s.charCodeAt(i) & 0xff;
}
return buf;
} else {
const buf = new Array(s.length);
for (let i = 0; i != s.length; ++i) {
buf[i] = s.charCodeAt(i) & 0xff;
}
return buf;
}
};
const createPosition = (colIndex: any, rowIndex: any) => {
rowIndex++;
if (colIndex >= 26) {
const n1 = Math.floor(colIndex / 26) - 1;
const n2 = colIndex % 26;
const s1 = String.fromCharCode(n1 + 65);
const s2 = String.fromCharCode(n2 + 65);
return s1 + s2 + rowIndex;
} else {
return String.fromCharCode(colIndex + 65) + rowIndex;
}
};