Example: 100k-Row Export
Large exports are what the Fast stream path is built for: 100k rows run in a Worker in the browser (the main thread only does one structured clone), with Fast stream finishing in ~0.8s.
Mock data preview
| Order ID | Date | Region | Product | Channel | Qty | Unit Price | Amount | Status |
|---|---|---|---|---|---|---|---|---|
| ORD-000001 | 2026-07-21 | 华东 | USB-C 扩展坞 | 线上 | 18 | 789.44 | 14209.92 | pending |
| ORD-000002 | 2026-07-28 | 西南 | 显示器支架 | 线上 | 5 | 1127.47 | 5637.35 | paid |
| ORD-000003 | 2026-07-15 | 东北 | 机械键盘 | 线下 | 1 | 898.61 | 898.61 | paid |
Implementation
ts
import { exportExcel } from "@marcusok/excel-exporter";
// rows: sales data from your business layer, fields matching the columns
// below (fetching is omitted here; the scenario uses 100k rows — the live
// demo generates mock data for the same sales scenario, with more columns)
const result = await exportExcel({
filename: "large-export-100k",
sheets: [
{
name: "Sales",
columns: [
{ prop: "orderId", label: "Order ID", width: 18 },
{ prop: "date", label: "Date", width: 12 },
{ prop: "amount", label: "Amount", width: 14 },
{ prop: "status", label: "Status", width: 10 },
],
data: rows,
},
],
mode: "auto", // ≥ 50k rows -> worker + stream
onProgress: (p) => setProgress(p),
});
console.log(result); // engine: "modern-xlsx", mode: "stream", rowCount: 100000Notes
- At 100k rows
autopicksworker + Fast stream: ~0.8s measured (vs 17.5s on the Workbook path); - The stream path supports multi-row headers and merges, but does not support styles/width/freeze/filter; a console warning is expected;
onProgressreports every 1000 rows;- Set
decimalsexplicitly on numeric columns for value consistency with the Workbook path.
Compare auto vs main at 100,000 rows in the play.