npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

bun-excel

v2.0.0

Published

High-performance, Bun-optimized library for reading and writing Excel and CSV files with streaming, styling, formulas, and hyperlinks

Readme

bun-excel

CI npm version GitHub stars License: MIT Bun TypeScript

English 中文

一个高性能、针对 Bun 优化的 TypeScript Excel (.xlsx) 和 CSV 库。

⚠️ Note: 运行时说明:bun-excel 使用 Bun.file()、Bun.write() 和 FileSink 等 Bun 特有 API。它面向 Bun 运行时,不兼容 Node.js 或 Deno。 参与项目之前,请先阅读我们的 Code of Conduct。 某些安全扫描工具可能会标记包内的 schemas.openxmlformats.org 等 URL。它们是 Excel OOXML 格式要求的命名空间和 relationship 标识符,并不是运行时网络请求。

为什么使用这个包

  • 为 Bun 而写,不是从 Node-first 抽象层改出来的 — 核心文件路径直接使用 Bun.file()、Bun.write()、FileSink 和 Bun 原生流式 API。
  • 与 Bun 原生文件目标(包括 S3)配合自然 — 支持读取和写入本地路径、Bun.file(...) 以及 Bun S3File 对象,流式导出也可以直接写入 S3 目标。
  • 面向 Bun backend 的生产导出 helper — 支持进度回调、AbortSignal、导出诊断、流式 Response helper,以及通过 Bun 原生 writer 选项调优 S3 multipart 上传。
  • TypeScript 优先的表格模型 — Workbook、Worksheet、Row、Cell 以及样式对象都清晰、实用,适合 Bun 应用直接使用。
  • 聚焦真实报表场景 — 样式、公式、超链接、数据验证、条件格式、自动筛选、冻结/拆分窗格以及工作簿元数据都已覆盖。
  • 按工作负载选择写入策略 — 小文件可直接写,大文件可用流式或磁盘落地分块写入来降低内存压力。

安装

bun add bun-excel

要求 Bun 1.4.0 或更新版本。

快速开始

写入 Excel

import { writeExcel, type Workbook } from "bun-excel";

const workbook: Workbook = {
  worksheets: [{
    name: "Sheet1",
    columns: [{ width: 20 }, { width: 15 }],
    rows: [
      {
        cells: [
          { value: "姓名", style: { font: { bold: true } } },
          { value: "分数", style: { font: { bold: true } } },
        ],
      },
      { cells: [{ value: "小明" }, { value: 95 }] },
      { cells: [{ value: "小红" }, { value: 87 }] },
    ],
  }],
};

await writeExcel("report.xlsx", workbook);

读取 Excel

import { readExcel } from "bun-excel";

const workbook = await readExcel("report.xlsx");
for (const sheet of workbook.worksheets) {
  console.log(`工作表: ${sheet.name}`);
  for (const row of sheet.rows) {
    console.log(row.cells.map(c => c.value).join(" | "));
  }
}

预览和选择性导入可使用 readExcelStream(),支持行范围、每个工作表的行数限制、列选择、取消和进度回调。

导入行数据之前,可使用 readExcelInfo() 查看工作表名称、可见状态及工作簿元数据。

使用 readExcelObjectsStream() 按表头流式读取带类型的对象,并获取单元格验证错误。

使用 readExcelValuesStream() 以有界批次读取单元格值,适用于不需要单元格元数据的数据导入。

readExcel() 可通过 includeImages: false、includeComments: false 和 includeTables: false 跳过图片、批注和表格。

通过 writeExcel(target, workbook, { password }) 和 buildExcelBuffer(workbook, { password }) 可导出需要密码打开的文件。支持范围和内存要求见密码加密导出。

CSV

import { readCSV, writeCSV } from "bun-excel";

// 写入
await writeCSV("data.csv", [
  ["姓名", "年龄"],
  ["小明", 28],
]);

// 读取
const csv = await readCSV("data.csv");

文档

完整 API 参考请查看 DOCUMENT.zh-CN.md,包括:

  • 所有函数(writeExcel、readExcel、writeCSV、readCSV、流式 API)
  • 类型定义(Workbook、Worksheet、Cell、Row 等)
  • 样式指南(字体、填充、边框、对齐、数字格式)
  • 功能说明(公式、超链接、合并单元格、冻结窗格、数据验证)
  • 写入模式对比(普通 vs 流式 vs 分块流式)

性能测试

于 2026-09-04 在 Bun 1.4.0 / macOS ARM64 上测量。各项数值为 3 次运行的中位数,每种模式使用独立进程。写入工作负载均导出单工作表的压缩 .xlsx 文件。

1,000,000 行 × 10 列

| 模式 | 总耗时 | 收尾耗时 | 每秒行数 | Peak RSS | 文件大小 | | --- | ---: | ---: | ---: | ---: | ---: | | createExcelStream() | 7.43s | 4.01s | 134,505 | 88.2 MiB | 54.31 MiB | | createChunkedExcelStream() | 6.80s | 3.28s | 147,004 | 94.4 MiB | 54.31 MiB |

bun run benchmark:1m

大型报表:30,000 行数据 × 30 列,包含 examples/large-report.ts 中的样式、合并单元格和页脚公式。

| 方法 | 总耗时 | Peak RSS | 采样峰值 heapUsed | 文件大小 | | --- | ---: | ---: | ---: | ---: | | writeExcel() | 0.86s | 337.0 MiB | 121.8 MiB | 5.90 MiB | | createExcelStream() | 0.94s | 81.7 MiB | 6.3 MiB | 6.03 MiB | | createChunkedExcelStream() | 0.96s | 82.5 MiB | 8.5 MiB | 6.03 MiB |

bun run benchmark

流式读取:readExcelStream()

在同一 Bun 1.4.0 运行时下,对比旧版读取器(自定义 XML 解析器)与当前 Bun XML 原生读取器。每个文件包含 30,009 行,含报表表头和页脚。每种实现使用独立进程交替运行 3 次,取中位数;耗时包含读取全部行并对 JSON 输出计算哈希。输出校验和一致。

| XLSX 文件 | 旧版耗时 | 原生版耗时 | 旧版 Peak RSS | 原生版 Peak RSS | | --- | ---: | ---: | ---: | ---: | | 共享字符串(bench-normal.xlsx) | 2.107s | 1.709s | 184.7 MiB | 174.6 MiB | | 内联字符串(bench-stream.xlsx) | 2.214s | 1.709s | 153.5 MiB | 149.4 MiB |

该对比涵盖完整读取流程,包括 XML 分批处理和 ZIP 解压,并非仅比较 XML 解析器。

Peak RSS 为操作系统记录的进程内存峰值,包含运行时开销;heapUsed 通过采样测量,可能遗漏短暂峰值。内存和文件大小使用 MiB。结果受机器和系统负载影响;RSS 不可与之前同一进程内的内存增量直接比较。

仅值批次读取

2026-09-05,Bun 1.4.0 / macOS ARM64:每个读取器在独立进程中交替运行三次,取中位数。两条路径提取相同值(含原始工作表/行号)并计算 SHA-256,校验结果一致。基线为当前 readExcelStream() 加值提取,与上方完整行对象的哈希测试不同。

| 数据集 | 逐行读取 + 值提取 | 值批次读取 | 逐行读取峰值 RSS | 值批次峰值 RSS | | --- | ---: | ---: | ---: | ---: | | 报表,共享字符串 · 30,009 行 | 1.135s | 1.034s | 166.6 MiB | 154.9 MiB | | 报表,内联字符串 · 30,009 行 | 1.133s | 1.017s | 155.6 MiB | 133.5 MiB | | 内联字符串 · 1,000,001 行 | 12.382s | 11.207s | 176.7 MiB | 161.3 MiB |

readExcelValuesStream() 使用默认选项。RSS 会随运行变化,表中为实测中位数,并非内存上限。复现:bun run examples/benchmark-read-values.ts output/bench-normal.xlsx;其他数据集改用 bench-stream.xlsx 或 benchmark-stream-1m.xlsx。通过 bun run benchmark 和 bun run benchmark:1m 生成测试文件。

示例

# 性能测试(普通 vs 流式 vs 分块流式)
bun run benchmark

# 1M 行 Excel 性能测试(流式 vs 分块流式)
bun run benchmark:1m

安全性

本库已进行安全加固:

  • XML 炸弹防护 — 深度限制、节点数量上限、输入大小验证
  • 路径遍历保护 — path.resolve() + 所有文件路径的空字节检查
  • Zip slip 防护 — 验证 ZIP 归档中的所有路径
  • 输入验证 — 最大行数 (1M)、最大列数 (16K)、最大文件大小 (200MB)
  • XML 注入防护 — 所有用户值均经过正确转义
  • 原型污染防护 — 动态映射使用 Object.create(null)

贡献

请查看 CONTRIBUTING.md 了解开发设置和指南。

许可证

MIT