123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- /*
- * @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;
|