Skip to content

高级特性 ​

多工作表 ​

sheets 是数组,一次调用即可生成多页工作簿:

ts
await exportExcel({
  filename: "department-report",
  sheets: [
    { name: "销售", columns: [...], data: salesData },
    { name: "人员", columns: [...], data: staffData },
  ],
});

工作表名需满足 ECMA-376 约束:非空、不超过 31 字符、不含 : \ / ? * [ ]、不得以单引号开头或结尾,且在 sheets 内不得重名——重名与违规一样走统一报错,而不会生成损坏文件或被静默改名。违反时不会生成损坏文件,也不会以异常形式抛出——输入在任何导出路由(及兜底链)运行前就被前置校验拦截,调用直接以 { success: false, error } 返回(错误信息明确)。

冻结行 ​

freezeRows: 1 冻结表头(映射到 frozenPane),浏览大表时表头始终可见。多级表头建议 freezeRows >= 表头行数,让所有表头行都保持可见。

多级表头 ​

列用 children 组成树形结构,即可生成多行表头;分组表头格会自动合并(跨其全部叶子列),叶子列表头自动纵向跨满剩余表头行——无需手工计算合并范围。

ts
await exportExcel({
  filename: "月度销售",
  sheets: [
    {
      name: "销售",
      freezeRows: 3,
      columns: [
        { prop: "product", label: "产品" },
        {
          label: "收入情况",
          children: [
            {
              label: "本月",
              children: [
                { prop: "m_qty", label: "数量" },
                { prop: "m_amt", label: "金额" },
              ],
            },
            {
              label: "本年累计",
              children: [
                { prop: "y_qty", label: "数量" },
                { prop: "y_amt", label: "金额" },
              ],
            },
          ],
        },
      ],
      data: [{ product: "A", m_qty: 1, m_amt: 2, y_qty: 3, y_amt: 4 }],
    },
  ],
});

生成 3 行表头:

行ABCDE
1产品收入情况(合并 B–E)
2本月(合并 B–C)本年累计(合并 D–E)
3数量金额数量金额

规则:

  • 叶子列(无 children)必须有 prop(或旧名 key);分组列可省略,只贡献表头;
  • width / style / format 只对叶子列生效;
  • 分组表头样式用该列的 headerStyle,叶子表头样式同理(未设置时回退到表级 headerStyle);
  • 任意路径(main / worker / stream,含流式兜底)都支持多级表头,stream 与兜底路径同样保留合并(样式除外)。

在线体验:下方是 sales-grouped 数据集的 mock 预览(两级分组表头,与导出文件的表头结构一致);到 play 演示站 的演示面板选择 sales-grouped 数据集即可导出带多级表头与数据区合并的真实文件。

Mock · 5 rows · seed 42
订单信息商品销售金额状态
订单号日期区域商品渠道数量单价金额
ORD-0000012026-07-21华东USB-C 扩展坞线上18789.4414209.92pending
ORD-0000022026-07-28西南显示器支架线上51127.475637.35paid
ORD-0000032026-07-15东北机械键盘线下1898.61898.61paid
ORD-0000042026-07-25华南机械键盘线上4360.061440.24refunded
ORD-0000052026-07-14华东机械键盘线下7643.84506.6paid

合并单元格 ​

ts
{
  name: "库存汇总",
  columns: [...],
  data: [...],
  merges: [
    { row: 0, col: 0, rowspan: 1, colspan: 2 }, // 第一行数据跨两列
  ],
}

MergeRange 相对数据区定位:row / col 从 0 开始(row 0 = 第一条数据行),rowspan / colspan 为跨度。

合并范围在所有路径上按同一规则校验:取值必须为整数,row/col ≥ 0,rowspan/colspan ≥ 1,范围不得超出数据区(叶子列数 / 数据行数),各合并范围之间不得重叠。非法输入最终以 { success: false, error } 返回并指明问题项——绝不生成 Excel 判定损坏的文件。

自动筛选 ​

autoFilter: true 在最后一行表头添加筛选下拉,范围覆盖该行及其下全部数据行(Excel 的筛选语义)。

进度与阶段回调 ​

ts
await exportExcel({
  ...,
  onProgress: (progress) => {
    // 0 → 1;首尾 0 与 1 由 exportExcel 在所有路径(含流式兜底)各上报一次;
    // 分段进度仅 stream 路径有(每 1000 行上报一次)
    bar.style.width = `${progress * 100}%`;
  },
  onPhase: (phase, durationMs) => {
    // phase: "init" | "build" | "download",严格按序执行
    console.log(`${phase} took ${durationMs.toFixed(1)}ms`);
  },
});

各阶段语义:

阶段说明
initWASM 初始化;main 路径每次导出上报(已加载约 0ms);Node 主线程的 stream 路径不加载 WASM,但会上报一次 0ms 以保持阶段序列一致;Worker + Workbook 仅 Worker 初始化时上报;Worker + stream 不上报;流式兜底上报一次 0ms
build工作簿构建(按实际构建次数报告,含兜底重试——失败后走流式兜底会再报告一次)
download浏览器触发下载(download: false 时不报告;Node 下无此阶段)

onPhase 只反映各阶段耗时,不影响 ExportResult.duration(主线程路由为整次导出总耗时;worker 路由的 duration 在主线程从调用 exportInWorker 起表,含 postMessage 前的序列化与 Worker 往返,直到 Blob 构造完成,因此比纯 Worker 内构建耗时更宽)。

基于这对回调开箱可用的全屏遮罩见进度遮罩。

关闭自动下载 ​

ts
const result = await exportExcel({ ..., download: false });
// result.blob 可直接使用

导出结果 ​

ts
interface ExportResult {
  success: boolean;
  blob?: Blob;
  engine?: "modern-xlsx"; // 实际使用的引擎
  mode?: ExportMode; // 实际使用的模式
  duration?: number; // 完整导出耗时 ms
  rowCount?: number;
  error?: Error;
}

建议在失败分支展示 result.error 并提示用户重试;导出成功但 result.error 非空时提示已降级(无样式流式导出)。