一、技术栈
二、核心函数:exportToExcel
export function exportToExcel<T>(data: T[], filename: string, sheetName = 'Sheet1') { // 1. 创建空工作簿 const workbook = XLSX.utils.book_new(); // 2. JSON转工作表(对象键→表头,值→数据行) const worksheet = XLSX.utils.json_to_sheet(data); // 3. 自动计算列宽(根据内容长度) const colWidths = Object.keys(data[0]).map((key) => { const maxLength = Math.max( key.length, ...data.map(row => String(row[key] || '').length) ); return { wch: Math.min(Math.max(maxLength + 2, 10), 50) }; }); worksheet['!cols'] = colWidths; // 4. 添加工作表并下载 XLSX.utils.book_append_sheet(workbook, worksheet, sheetName); XLSX.writeFile(workbook, `${filename}.xlsx`);}
三、数据转换层
// 算力中心导出示例export function exportComputeCenterLog(data, getChangeTypeText) { const exportData = data.map(item => ({ '流水号': item._id, '创建时间': formatDate(item.createdAt), '类型': getChangeTypeText(item.changeType), '算力变化': item.changeValue >= 0 ? `+${item.changeValue}` : item.changeValue, '用户备注': item.description || '--', })); const filename = `算力中心记录_${formatDate(Date.now()).replace(/[\s:]/g, '-')}`; exportToExcel(exportData, filename, '算力中心记录');}
四、分页数据聚合
const handleExport = async () => { toast.loading('正在获取数据...'); const allList = []; let currentPage = 1; const pageSize = 100; // 循环获取所有数据 while (true) { const res = await fetchData({ page: currentPage, size: pageSize }); allList.push(...res.data); if (allList.length >= res.totalSize) break; currentPage++; } exportComputeCenterLog(allList, getChangeTypeText); toast.success(`成功导出 ${allList.length} 条记录`);};
五、关键点
列宽计算:遍历每列,取表头与数据最大长度,限制在 10-50 字符数据转换:API 字段 → 中文表头,处理日期、枚举、空值分页聚合:循环获取,每次 100 条,直到获取全部核心:通用函数 + 业务转换函数 + 分页聚合策略。