refactor(reports): 优化报表导出和数据处理逻辑

- 异步动态引入 XLSX 库以优化加载性能
- 抽取导出表格为工作簿的异步函数,提高代码复用性
- 使用构建函数封装报表数据行和汇总的生成逻辑
- 替换硬编码数据聚合为调用构建函数,简化代码结构
- 在导出功能中支持异步操作,增强用户体验
- 统一格式化和统计报表数据,提升代码可维护性
This commit is contained in:
2026-06-10 11:06:44 +08:00
parent dfd475856e
commit 1c80a3ae75
2 changed files with 182 additions and 81 deletions

View File

@@ -3,7 +3,6 @@
import { Download } from "lucide-react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import * as XLSX from "xlsx";
import { Button } from "@/components/ui/button";
@@ -60,6 +59,17 @@ function stripOmittedColumns(table: HTMLTableElement): HTMLTableElement {
return clone;
}
async function exportTableToWorkbook(table: HTMLTableElement, sheetName: string, filename: string): Promise<void> {
const XLSX = await import("xlsx");
const exportTable = stripOmittedColumns(table);
const workbook = XLSX.utils.table_to_book(exportTable, {
sheet: sheetName,
raw: true,
});
const safeName = filename.endsWith(".xlsx") ? filename : `${filename}.xlsx`;
XLSX.writeFile(workbook, safeName);
}
export function AdminTableExportButton({
tableId,
filename,
@@ -73,7 +83,7 @@ export function AdminTableExportButton({
}) {
const { t } = useTranslation("common");
const onExport = () => {
const onExport = async () => {
const table = document.getElementById(tableId);
if (!(table instanceof HTMLTableElement)) {
toast.error(t("toast.exportFailed"));
@@ -81,13 +91,7 @@ export function AdminTableExportButton({
}
try {
const exportTable = stripOmittedColumns(table);
const workbook = XLSX.utils.table_to_book(exportTable, {
sheet: sheetName,
raw: true,
});
const safeName = filename.endsWith(".xlsx") ? filename : `${filename}.xlsx`;
XLSX.writeFile(workbook, safeName);
await exportTableToWorkbook(table, sheetName, filename);
toast.success(t("toast.exportDone"));
} catch {
toast.error(t("toast.exportFailed"));