Files
ln-bi/src/modules/assets/library/export.tsx
T
2026-09-23 14:28:26 +08:00

53 lines
1.3 KiB
TypeScript

import { Download } from "lucide-react";
import { Button } from "@/components/ui/button";
import type { Column } from "./DataGrid";
function cellValue<T extends object>(row: T, col: Column<T>): string | number {
const raw = row[col.key];
if (col.format) return col.format(raw, row);
return (raw as string | number) ?? "";
}
/** 按表格列定义导出 xlsx;xlsx 按需加载,避免进入首屏包。 */
export async function exportToXlsx<T extends object>(
rows: T[],
columns: Column<T>[],
filename: string,
sheetName = "明细",
): Promise<void> {
const { buildJsonSheet, writeWorkbook } = await import("../../../shared/xlsx");
const sheet = buildJsonSheet(
rows.map((row) =>
Object.fromEntries(columns.map((col) => [col.label, cellValue(row, col)])),
),
);
writeWorkbook([{ name: sheetName, sheet }], filename);
}
export function ExportButton<T extends object>({
rows,
columns,
filename,
sheetName,
label = "导出",
}: {
rows: T[];
columns: Column<T>[];
filename: string;
sheetName?: string;
label?: string;
}) {
return (
<Button
variant="outline"
size="sm"
className="min-h-9 w-fit md:min-h-7"
disabled={!rows.length}
onClick={() => void exportToXlsx(rows, columns, filename, sheetName)}
>
<Download data-icon="inline-start" />
{label}
</Button>
);
}