Skip to content

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 ​

Mock · 5 rows · seed 42
SKUProductCategoryWarehouseStockSafety StockUnitUpdatedStatus
SKU-000014K 摄像头配件上海仓48156件2026-07-17in-stock
SKU-000024K 摄像头影音上海仓21870件2026-07-28in-stock
SKU-00003无线鼠标配件广州仓59744件2026-07-19in-stock
SKU-000044K 摄像头外设广州仓358件2026-07-01low
SKU-00005无线鼠标家具广州仓21325件2026-07-01in-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 lowStock style (bold red + light red fill) highlights risk items — note that a column-level style applies 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 style applies to the whole data column — a good fit for status columns;
  • merges are positioned relative to the data area;
  • Small data (< 20,000 rows) stays on the styled main path with default auto.