/* * @Author: code4eat awesomedema@gmail.com * @Date: 2023-05-31 11:18:30 * @LastEditors: code4eat awesomedema@gmail.com * @LastEditTime: 2024-09-10 10:31:52 * @FilePath: /BudgetManaSystem/src/utils/tableToExcel.ts * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ import * as XLSX from 'xlsx'; import { saveAs } from 'file-saver'; type DataType = { [key: string]: string | number | null }; type Column = { title: string; dataIndex: string; key: string; children?: Column[]; }; type Merge = { s: { r: number; c: number }; e: { r: number; c: number }; }; function getMerges(columns: Column[], startRow = 0, startCol = 0): Merge[] { let merges: Merge[] = []; let colIndex = startCol; for (const column of columns) { let endRow = startRow; let endCol = colIndex; if (column.children) { // 如果有子列,递归处理子列 const childMerges = getMerges(column.children, startRow + 1, colIndex); merges = merges.concat(childMerges); // 计算结束列的位置 endCol += column.children.length - 1; } // 添加合并项 merges.push({ s: { r: startRow, c: colIndex }, e: { r: endRow, c: endCol } }); // 更新列索引 colIndex = endCol + 1; } return merges; } function exportTableToExcel(tableData: DataType[], columns: Column[], fileName = 'data') { // 获取列标题 const columnHeaders = columns.map(column => column.title); // 将列标题和表格数据合并 const allData = [columnHeaders as any].concat( tableData.map(row => Object.values(row).map(value => (typeof value === 'string' ? value : value) ) ) ); // 获取合并项 const merges = getMerges(columns); // 创建一个新的工作簿 const wb = XLSX.utils.book_new(); // 将数据转化为工作表 const ws = XLSX.utils.aoa_to_sheet(allData); // 设置合并项 ws['!merges'] = merges; // 自动计算列宽 const colWidths = allData[0].map((col: any, index: number) => { const maxLength = allData.reduce((max, row) => { const cellValue = row[index] ? row[index].toString() : ''; return Math.max(max, cellValue.length); }, 0); return { wch: maxLength + 2 }; // 加上额外的2个字符的宽度来提供一些空间 }); ws['!cols'] = colWidths; // 设置工作表的列宽 // 将工作表添加到工作簿中 XLSX.utils.book_append_sheet(wb, ws, 'Sheet1'); // 将工作簿转化为blob const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'array' }); const blob = new Blob([wbout], { type: 'application/octet-stream' }); // 使用file-saver保存文件 saveAs(blob, `${fileName}.xlsx`); } export default exportTableToExcel;