Example: Inventory Ledger Export
Inventory ledgers should make risk items stand out. This example combines a custom CellStyle (applied to the whole column) with enum mapping.
Mock data preview
| SKU | Product | Category | Warehouse | Stock | Safety Stock | Unit | Updated | Status |
|---|---|---|---|---|---|---|---|---|
| SKU-00001 | 4K 摄像头 | 配件 | 上海仓 | 481 | 56 | 件 | 2026-07-17 | in-stock |
| SKU-00002 | 4K 摄像头 | 影音 | 上海仓 | 218 | 70 | 件 | 2026-07-28 | in-stock |
| SKU-00003 | 无线鼠标 | 配件 | 广州仓 | 597 | 44 | 件 | 2026-07-19 | in-stock |
| SKU-00004 | 4K 摄像头 | 外设 | 广州仓 | 3 | 58 | 件 | 2026-07-01 | low |
| SKU-00005 | 无线鼠标 | 家具 | 广州仓 | 213 | 25 | 件 | 2026-07-01 | in-stock |
Implementation
ts
import { exportExcel } from "@marcusok/excel-exporter";
import type { CellStyle } from "@marcusok/excel-exporter";
// rows: inventory data from your business layer, fields matching the
// columns below (fetching is omitted here)
const lowStock: CellStyle = {
font: { color: "C00000", bold: true },
fill: { pattern: "solid", fgColor: "FDE2E2" },
};
const result = await exportExcel({
filename: "inventory-2026-07",
sheets: [
{
name: "Inventory",
freezeRows: 1,
autoFilter: true,
columns: [
{ prop: "sku", label: "SKU", width: 16 },
{ prop: "name", label: "Product", width: 20 },
{ prop: "category", label: "Category", width: 10 },
{ prop: "warehouse", label: "Warehouse", width: 12 },
{
prop: "stock",
label: "Stock",
width: 10,
format: { type: "number", thousands: true },
style: lowStock, // highlights the whole stock column
},
{ prop: "safetyStock", label: "Safety Stock", width: 12 },
{ prop: "unit", label: "Unit", width: 8 },
{
prop: "updatedAt",
label: "Updated",
width: 12,
format: { type: "date" },
},
{
prop: "status",
label: "Status",
width: 10,
format: {
type: "enum",
map: { "in-stock": "OK", low: "Low", out: "Out" },
fallback: "Unknown",
},
},
],
data: rows,
merges: [{ row: 0, col: 0, rowspan: 1, colspan: 2 }],
},
],
});Notes
- The custom
lowStockstyle (bold red + light red fill) highlights risk items — note that a column-levelstyleapplies to every data row in the column; per-row conditional styling is not supported, so use the status column's enum labels to flag individual risk items; - Column-level
styleapplies to the whole data column — a good fit for status columns; mergesare positioned relative to the data area;- Small data (< 20,000 rows) stays on the styled
mainpath with defaultauto.