import * as XLSX from 'xlsx'; import type { MonitoringVehicle } from './types'; interface ExportContext { date: string; sortBy: 'today' | 'total'; } const HEADERS = [ '状态', '车牌号', '客户', '业务部门', '项目', '租赁状态', '运营区域', '今日里程(km)', '累计里程(km)', ] as const; function statusLabel(v: MonitoringVehicle): string { if (!v.isDataSynced) return '未对接'; return v.isOnline ? '在线' : '离线'; } function mileageCell(v: MonitoringVehicle, kind: 'today' | 'total'): string | number { if (!v.isDataSynced) return '未对接'; if (kind === 'today') return Math.max(0, Math.round(v.dailyKm || 0)); return v.totalKm != null ? Math.round(v.totalKm) : '未对接'; } export function exportMileageXlsx(vehicles: MonitoringVehicle[], ctx: ExportContext): void { const data: (string | number)[][] = [ [...HEADERS], ...vehicles.map(v => [ statusLabel(v), v.plate, v.customer || '', v.department || '', v.project || '', v.rentStatus || '', v.region || '', mileageCell(v, 'today'), mileageCell(v, 'total'), ]), ]; const ws = XLSX.utils.aoa_to_sheet(data); ws['!cols'] = [ { wch: 8 }, // 状态 { wch: 12 }, // 车牌号 { wch: 28 }, // 客户 { wch: 14 }, // 业务部门 { wch: 16 }, // 项目 { wch: 10 }, // 租赁状态 { wch: 12 }, // 运营区域 { wch: 14 }, // 今日里程 { wch: 14 }, // 累计里程 ]; ws['!freeze'] = { xSplit: 0, ySplit: 1 } as never; // 表头样式(在客户端 SheetJS 社区版仅基本样式生效) for (let c = 0; c < HEADERS.length; c++) { const ref = XLSX.utils.encode_cell({ r: 0, c }); if (ws[ref]) { (ws[ref] as { s?: unknown }).s = { font: { bold: true, color: { rgb: 'FFFFFF' } }, fill: { fgColor: { rgb: '2563EB' } }, alignment: { horizontal: 'center', vertical: 'center' }, }; } } const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, '里程明细'); const now = new Date(); const y = now.getFullYear(); const m = String(now.getMonth() + 1).padStart(2, '0'); const d = String(now.getDate()).padStart(2, '0'); const hh = String(now.getHours()).padStart(2, '0'); const mm = String(now.getMinutes()).padStart(2, '0'); const dateTag = ctx.date ? ctx.date.replace(/-/g, '') : `${y}${m}${d}`; const filename = `里程看板_${dateTag}_${hh}${mm}_${ctx.sortBy === 'today' ? '今日' : '累计'}.xlsx`; XLSX.writeFile(wb, filename); }