@chronicstone/typed-xlsx
v1.0.4
Published
High-quality type-safe Excel reporting.
Downloads
7,839
Maintainers
Readme
typed-xlsx
Type-safe Excel reporting for TypeScript, with one clean schema API and two workbook modes:
createWorkbook()for polished buffered exportscreateWorkbookStream()for large commit-based exports
What you get
- Typed path accessors and accessor callbacks
- Column transforms, defaults, styling, and formatting
- Multi-row summaries with reducer-based APIs
- Multi-sheet workbooks and multi-table buffered layouts
- Freeze panes, RTL sheets, row expansion, merges, and auto sizing
- Streamed XLSX generation for very large exports
Installation
pnpm add @chronicstone/typed-xlsxBuffered example
import { createExcelSchema, createWorkbook } from "@chronicstone/typed-xlsx";
type Order = {
id: string;
customer: {
name: string;
email: string;
};
items: Array<{
sku: string;
quantity: number;
unitPrice: number;
}>;
};
const schema = createExcelSchema<Order>()
.column("orderId", {
header: "Order",
accessor: "id",
})
.column("customerName", {
header: "Customer",
accessor: "customer.name",
})
.column("sku", {
header: "SKU",
accessor: (row) => row.items.map((item) => item.sku),
})
.column("lineTotal", {
header: "Line Total",
accessor: (row) => row.items.map((item) => item.quantity * item.unitPrice),
style: {
numFmt: "$#,##0.00",
},
summary: (summary) => [
summary.label("TOTAL"),
summary.cell({
init: () => 0,
step: (acc, row) =>
acc + row.items.reduce((sum, item) => sum + item.quantity * item.unitPrice, 0),
finalize: (acc) => acc,
style: {
numFmt: "$#,##0.00",
},
}),
],
})
.build();
const workbook = createWorkbook();
workbook
.sheet("Orders", {
freezePane: { rows: 1 },
})
.table({
id: "orders",
rows,
schema,
});
const bytes = workbook.toUint8Array();Stream example
import { createExcelSchema, createWorkbookStream } from "@chronicstone/typed-xlsx";
const schema = createExcelSchema<{ amount: number; id: string }>()
.column("id", {
header: "ID",
accessor: "id",
})
.column("amount", {
header: "Amount",
accessor: "amount",
summary: (summary) => [
summary.cell({
init: () => 0,
step: (acc, row) => acc + row.amount,
finalize: (acc) => acc,
style: { numFmt: "$#,##0.00" },
}),
],
})
.build();
const workbook = createWorkbookStream({
tempStorage: "file",
memoryProfile: "low-memory",
});
const table = await workbook
.sheet("Transactions", {
freezePane: { rows: 1 },
})
.table({
id: "transactions",
schema,
});
for await (const batch of getTransactionBatches()) {
await table.commit({ rows: batch });
}
await workbook.writeToFile("./transactions.xlsx");Notes on migration
This release promotes the new API as the main package surface.
keybecomesaccessor- summaries use reducer functions:
init,step,finalize - selection uses
include/exclude - styles use the library's own normalized
CellStyle - stream workbooks support
memoryProfile/stringsto tune memory usage and file size
License
MIT License © 2023-PRESENT Cyprien THAO
