/* * 导出相关工具(最小落地版) * 仅抽离现有 calcPageTemplate 的导出格式化逻辑,避免页面过重 */ import { ProColumns } from '@ant-design/pro-components'; import exportTableToExcel from './tableToExcel'; import { formatMoneyNumber, formatToPercentage } from './format'; export interface ExportOptions { // 页面 key,用于处理特殊格式化 calcPageKey?: string; // 是否为树形数据时需要缩进的列 indentColumn?: string; } /** * 根据当前列与数据,进行必要的格式化与树形缩进,并导出为 Excel * 注意:本方法内的“wholeHospCostCalculate”逻辑与原实现保持一致,避免行为变化 */ export function exportCalcPageDataToExcel( columns: ProColumns[], totalData: any[], options: ExportOptions = {} ) { const { calcPageKey, indentColumn } = options; // 生成表头 const headers: { [key: string]: any } = {}; columns.forEach((a: any) => { headers[`${a.dataIndex}`] = a.title; }); // 列配置索引,便于判断数值列 const columnMap = new Map(); (columns as any[])?.forEach?.((c) => { if (c && c.dataIndex) columnMap.set(String(c.dataIndex), c); }); // 递归处理数据(支持 children),并为 indentColumn 添加缩进 const data: any[] = []; const processData = (items: any[], level: number = 0) => { items.forEach(item => { const row: { [key: string]: any } = {}; Object.keys(headers).forEach(key => { if (indentColumn && key === indentColumn) { // 使用 Unicode 不可见空格来缩进 row[`${key}`] = `${'\u00A0'.repeat(level * 4)}${item[`${key}`]}`; } else if (item.children && item.children.length > 0 && (calcPageKey !== 'wholeHospCostCalculate')) { // 非全院损益时,有 children 的父节点导出为空字符串 row[`${key}`] = ''; } else { if (calcPageKey === 'wholeHospCostCalculate') { if (key === 'amount') { const { decimalPlace, permil, dataType, children, calcType } = item; if (children && children.length > 0 && calcType === '0') { row[`${key}`] = ''; } else if (dataType === 2) { row[`${key}`] = typeof item[`${key}`] === 'number' && !isNaN(item[`${key}`]) ? `${(item[`${key}`] * 100).toFixed(decimalPlace || 2)}%` : item[`${key}`]; } else { const formatOptions = { decimalPlaces: decimalPlace !== undefined ? decimalPlace : 2, useThousandSeparator: permil === 1, }; row[`${key}`] = formatMoneyNumber(item[`${key}`], formatOptions); } } else if (key === 'percent') { const { children, calcType } = item; row[`${key}`] = (children && children.length > 0 && calcType === '0') ? '' : formatToPercentage(item[`${key}`]); } else { row[`${key}`] = item[`${key}`]; } } else if (calcPageKey === 'deptDirectMedicalCost' || calcPageKey === 'deptFullDirectCost' || calcPageKey === 'hospitalVisitCostComposition' || calcPageKey === 'hospitalDeptVisitCost' || calcPageKey === 'deptCostAllocationSummary' || calcPageKey === 'hospitalBedDayCostComposition') { // 这两个页面导出需要默认启用千分号,并按行的 decimalPlace 控制小数位 const col = columnMap.get(key); const isNumericColumn = col && (col.align === 'right'); if (isNumericColumn) { const decimalPlaces = (typeof item?.decimalPlace === 'number') ? item.decimalPlace : 2; row[`${key}`] = formatMoneyNumber(item[`${key}`], { decimalPlaces, useThousandSeparator: true }); } else { row[`${key}`] = item[`${key}`]; } } else { row[`${key}`] = item[`${key}`]; } } }); data.push(row); if (item.children && item.children.length > 0) { processData(item.children, level + 1); } }); }; processData(totalData); // 根据页面 key 设定导出文件名 const fileNameMap: Record = { wholeHospCostCalculate: '全院损益报表', projectCostCalc: '项目成本计算', deptDirectMedicalCost: '医院科室直接成本表(医疗成本)', deptFullDirectCost: '医院科室直接成本表(全成本)', clinicalDeptMedicalCost: '临床服务类科室全成本(医疗成本)', clinicalDeptFullCost: '临床服务类科室全成本(全成本)', clinicalDeptFullCostAnalysis: '临床服务类科室全成本构成分析表', deptCostAllocationSummary: '医院科室成本分摊汇总表', hospitalVisitCostComposition: '医院诊次成本构成表', hospitalBedDayCostComposition: '医院床日成本构成表', }; const fileName = (calcPageKey && fileNameMap[calcPageKey]) ? fileNameMap[calcPageKey] : '项目成本计算'; exportTableToExcel(data, columns as any[], fileName); }