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;// title重命名const tableTitle = `${title}_评论数据_${dayjs().format("YYYY-MM-DD_HH_mm_ss")}`;// 创建一个工作簿const wb = XLSX.utils.book_new();// 添加sheet到工作簿中addSheet({xl: XLSX,wb,data,header,tableTitle,});// 文件存储成blob流数据(二进制流)const tmpDown = new Blob([s2ab(// 为了解决样式丢失问题只能用XLSXD来进行转换XLSXS.write(wb, {bookType: "xlsx",type: "binary",})) as any,]);// 下载二进制流(title是下载文件的名字)downExcel(tmpDown, tableTitle + ".xlsx");
}/*** 添加sheet页* @param info* wb: 工作簿* xl: XSLX库* data: 表格数据* header: 表格头* title: 表格标题**/
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);});// excelData:第一行是表头其他行是数据// xl.utils.aoa_to_sheet: 将js数据转换成excel数据,类型是A1,A2,A3,B1,B2,B3......,并创建sheetconst tableData = xl.utils.aoa_to_sheet(excelData); // 此处excelData为表格的数据// tableData格式:[excel对应的行列:{v:值,s:表格显示配置}]// tableData['!cols']:定义导出表格每列的宽度,从左到右依次对应header中从左到右的列tableData["!cols"] = [];tableData["!rows"] = [{ hpx: 40 }, { hpx: 40 }, { hpx: 40 }];// 给导出的excel做样式处理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;}// 格式化tableData数据格式,添加样式excelData.forEach((row, rowIndex) => {// 该数据对应的单元格位置const cellPosition = createPosition(colIndex, rowIndex);if (tableData[cellPosition]) {// 单元格的样式/主题(如果适用)tableData[cellPosition].s = {// 数据水平垂直居中alignment: {horizontal: "left",vertical: "center",},fill: {// 背景色// fgColor: { rgb: "FEE8D9" },},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" } },},// border: {// right: {// style: "dashed",// color: { rgb: "FFFFFF" },// },// },};// 第一行if (rowIndex === 0) {tableData[cellPosition].s.fill = {// 背景色// fgColor: { rgb: "fb731a" },};tableData[cellPosition].s.font = {// 字体sz: "12",// color: { rgb: "FFFFFF" },bold: true,shadow: true,};} else if (typeof row[colIndex] === "string" &&row[colIndex].includes("%")) {// 格式化百分号数据为excel中的number类型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";}}});});// 将sheet追加到工作簿, wb:工作簿,tableData:新的sheet,title:sheet名称// sheet 名称 不能 超过 31 位,否则 会报错xl.utils.book_append_sheet(wb, tableData, tableTitle.substring(0, 31)); // title为自定义的sheet表名
};// 自定义下载文件方法
/*** 使用a标签将文件进行下载* @param obj blob流数据* @param fileName 文件名*/
const downExcel = (obj: any, fileName: string) => {const a_node = document.createElement("a");a_node.download = fileName;if ("msSaveOrOpenBlob" in navigator) {// msSaveOrOpenBlob 方法允许用户在客户端上下载文件(navigator as any).msSaveOrOpenBlob(obj, fileName);} else {// createObjectURL根据传入的参数创建一个指向该参数对象的URL.a_node.href = URL.createObjectURL(obj);}a_node.click();//setTimeout(() => {// 释放一个通过URL.createObjectURL()创建的对象URLURL.revokeObjectURL(obj);}, 2000);
};/*** 文件流转换:将二进制字符串转换成对应的Unicode编码数组* @param s 文件的二进制字符串* @returns 返回存储文件数据的buffer或数组*/
const s2ab = (s: any) => {if (typeof ArrayBuffer !== "undefined") {// buffer存储// 在内存中分配s.length个的字节空间const buf = new ArrayBuffer(s.length);// Uint8Array 数组类型表示一个 8 位无符号整型数组,创建时内容被初始化为 0const view = new Uint8Array(buf);// 将二进制字符串转换成Unicode编码存储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;}
};// 行数 需要 小于 26 * 26
/**** @param colIndex 该数据对应列数* @param rowIndex 该数据对应的行数* @returns 返回的是该数据对应的单单元个位置*/
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 {// fromCharCode:将 Unicode 编码转为一个字符 (65对应A)return String.fromCharCode(colIndex + 65) + rowIndex;}
};
xlsx实现excel下载功能——js
2025/2/23 1:12:42
来源:https://blog.csdn.net/mantou_riji/article/details/139997626
浏览:
次
关键词:xlsx实现excel下载功能——js
版权声明:
本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。
我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com