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

stream-sheet-export

v1.1.0

Published

Browser-side streaming Excel/CSV exporter. Supports remote CSV/Excel URLs (CORS transform or direct download), JSON rows, AsyncIterable, custom formats and cell styles.

Readme

stream-sheet-export

npm version license

浏览器端 流式 Excel / CSV 导出工具库。

仓库:chenscDev/stream-sheet-export

  • 支持 S3 / 预签名 CSV 或 Excel URL:解析转换(需 CORS)或直链下载
  • 远程 Excel 可按表头字段匹配后自定义格式 / 单元格样式再导出
  • 支持 JSON 行数据AsyncIterable 分页边拉边导
  • 支持列格式:numFmt 格式串 / 内置 format 枚举 / render 自定义展示
  • 支持单元格(行 / 列)自定义样式:背景色、字体色、加粗、对齐等
  • 支持导出行数上限(默认 300 万)、单 Sheet 拆分(默认 100 万行)
  • 提供 Vite 插件自动拷贝 CSV Service Worker;也可用 npm / <script> CDN 引入

仅浏览器环境。不依赖 Vue / React。

安装

npm install stream-sheet-export
# 或
pnpm add stream-sheet-export

CDN(UMD):

<script src="https://unpkg.com/stream-sheet-export/dist/index.global.js"></script>
<script>
  const { createExporter } = StreamSheetExport;
</script>

快速开始

JSON → Excel

import { createExporter } from 'stream-sheet-export';

const exporter = createExporter({
  fileName: '订单明细',
  maxRows: 3_000_000,
  rowsPerSheet: 1_000_000,
  columns: [
    { key: 'id', title: '订单号', format: 'text', width: 18 },
    {
      key: 'amount',
      title: '金额',
      format: 'currency_cny',
      style: { align: 'right' },
    },
    {
      key: 'rate',
      title: '转化率',
      // 也可直接传 Excel 格式串
      numFmt: '0.00%',
      render: (v) => (typeof v === 'number' ? v : Number(v) || 0),
    },
    {
      key: 'status',
      title: '状态',
      render: (v) => (v === 1 ? '成功' : '失败'),
    },
  ],
  headerStyle: { bold: true, fill: '#F2F3F5' },
  stripeFill: '#FAFAFA',
  cellStyleResolver: ({ column, displayValue }) => {
    if (column.key === 'status' && displayValue === '失败') {
      return { fontColor: '#F56C6C', bold: true };
    }
    return null;
  },
  onProgress: (p) => console.log(p.phase, p.rows),
});

await exporter.exportExcelFromRows([
  { id: 'A001', amount: 12.5, rate: 0.128, status: 1 },
  { id: 'A002', amount: 9, rate: 0.02, status: 0 },
]);

远程 CSV / Excel URL → Excel(解析转换)

transform 模式(默认)会拉取并解析远程文件,再按 columns 做格式/样式后重新导出。 需要下载链接允许浏览器跨域读取(CORS),不限 CSV,Excel(.xlsx)同样支持。

// CSV 预签名链接
await exporter.exportExcelFromUrl(
  'https://your-bucket.s3.amazonaws.com/result.csv?X-Amz-Signature=...',
  {
    fileName: '报表导出',
    sourceType: 'auto', // auto | csv | xlsx
    fieldMap: { f_1001: '日期', f_1002: 'GMV' },
    formatMap: { f_1002: '"$"#,##0.00' },
  }
);

// Excel 下载链接:按源表头匹配列,再自定义格式/样式
await exporter.exportExcelFromUrl(
  'https://cdn.example.com/reports/orders.xlsx',
  {
    fileName: '订单导出',
    sourceType: 'xlsx',
    sheet: 0, // 或 sheet 名称
    columns: [
      {
        key: 'orderId',
        matchHeaders: ['订单号', 'Order ID'], // 匹配源表头
        title: '订单编号',
        format: 'text',
      },
      {
        key: 'amount',
        matchHeaders: ['金额', 'GMV'],
        title: '成交金额',
        format: 'currency_cny',
        style: { align: 'right' },
      },
      {
        key: 'status',
        matchHeaders: ['状态'],
        render: (v) => (String(v) === '1' ? '成功' : '失败'),
      },
    ],
    cellStyleResolver: ({ column, displayValue }) =>
      column.key === 'status' && displayValue === '失败'
        ? { fontColor: '#F56C6C', bold: true }
        : null,
  }
);

直链下载(不解析)

不改内容、不要求能解析表格;适合「只是把可下载链接存到本地」:

// 方式 1:专用 API
await exporter.downloadFromUrl(fileUrl, { fileName: '原始文件' });

// 方式 2:在 export*FromUrl 上指定 urlMode
await exporter.exportExcelFromUrl(fileUrl, { urlMode: 'direct', fileName: '原始文件' });
await exporter.exportCsvFromUrl(fileUrl, { urlMode: 'direct' });

transform 需要 CORS;direct 在 CORS 失败时会自动降级为 <a download> 直链。

AsyncIterable 分页边拉边导

async function* fetchPages() {
  let page = 1;
  while (true) {
    const { list, hasMore } = await api.getPage(page);
    for (const row of list) yield row;
    if (!hasMore) break;
    page += 1;
  }
}

await exporter.exportExcelFromAsyncIterable(fetchPages(), {
  fileName: '分页导出',
  columns: [/* ... */],
});

CSV 导出(URL 流式 / JSON)

// URL:仅替换表头,其余字节零拷贝 pipe 给 Service Worker,触发浏览器原生下载
await exporter.exportCsvFromUrl(csvUrl, {
  fileName: '报表',
  fieldMap: { id: '编号', name: '名称' },
});

// JSON → CSV
await exporter.exportCsvFromRows(rows, { fileName: '报表', columns });

Vite 插件(自动拷贝 SW)

CSV 流式下载依赖同源 Service Worker 文件。

// vite.config.ts
import { defineConfig } from 'vite';
import { streamSheetExport } from 'stream-sheet-export/vite';

export default defineConfig({
  plugins: [streamSheetExport()],
});

插件会:

  1. csv-export-sw.js 写入 public/
  2. 构建时写入 outDir
  3. Dev Server 中间件直接响应 /csv-export-sw.js

非 Vite 项目可手动拷贝:

cp node_modules/stream-sheet-export/dist/sw/csv-export-sw.js public/csv-export-sw.js

或通过选项自定义路径:

createExporter({
  serviceWorkerUrl: '/assets/csv-export-sw.js',
  csvFallback: 'direct', // 'direct' | 'blob' | 'throw'
});

API

createExporter(config?)

返回:

| 方法 | 说明 | |------|------| | exportExcelFromUrl(url, options?) | 远程 CSV/Excel → xlsx(urlMode: transform\|direct) | | exportExcelFromRows(rows, options?) | JSON/二维数组 → xlsx | | exportExcelFromAsyncIterable(source, options?) | 异步迭代 → xlsx | | exportCsvFromUrl(url, options?) | 远程 CSV 流式下载或直链 | | exportCsvFromRows(rows, options?) | JSON → csv | | downloadFromUrl(url, options?) | 任意可下载链接直链导出 |

常用选项

| 选项 | 默认 | 说明 | |------|------|------| | fileName | export_${Date.now()} | 文件名(自动补扩展名) | | columns | — | 列定义(title / format / numFmt / render / style) | | maxRows | 3000000 | 最大数据行 | | rowsPerSheet | 1000000 | 单 Sheet 拆分行数 | | sheetNamePrefix | Sheet | Sheet 名前缀 | | autoDownload | true | 是否自动触发下载 | | onProgress | — | 进度回调 | | signal | — | AbortSignal 取消 | | cellStyleResolver | — | 逐单元格样式 | | headerStyle / stripeFill | — | 表头 / 斑马纹 | | fieldMap / formatMap | — | URL 源快捷表头与格式映射 | | urlMode | transform | transform 解析转换 / direct 直链下载 | | sourceType | auto | auto / csv / xlsx | | sheet | 0 | 远程 Excel 读取的 sheet 下标或名称 | | matchHeaders(列上) | — | 匹配源表头别名 |

格式枚举 format

text | integer | number | number_2 | percent | percent_2 | currency_usd | currency_cny | date | datetime

优先级:numFmt > format > formatMap[key]

错误类型

  • ExportError:通用错误(含 code
  • ExportLimitError:超过 maxRows
  • ExportAbortError:被 AbortSignal 取消

浏览器兼容性

  • 现代 Chromium / Firefox / Safari(需 ReadableStreamfetch
  • CSV SW 方案需 HTTPS 或 localhost,并支持 transferable ReadableStream
  • 不支持 SW 时按 csvFallback 降级