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

@gantfdt/office-sdk

v1.3.0

Published

GantOffice 一体化 Office SDK:Univer 文档/表格/演示引擎 + OOXML 基线保留读写 + PDF 解析与查看器 + 可装配工作台 UI。react/react-dom 由宿主提供(peerDependencies);@univerjs/* 与 rxjs 为精确锁定的运行时依赖,其余第三方引擎已全部打进 dist,安装即用。

Readme

@gantfdt/office-sdk

GantOffice 一体化 Office SDK:文档(DOCX)/ 表格(XLSX)/ 演示(PPTX)/ PDF 的解析、编辑、预览与可装配工作台 UI,单一 npm 包、多入口按需引用。

  • 运行时策略:react / react-dom 由宿主提供(peerDependencies,避免双 React 实例);@univerjs/* 与 rxjs 为精确锁版运行时依赖(与构建时同版本,请勿单独升级);其余第三方引擎(pdfjs-dist、jszip、xlsx、pdf-lib 等)已全部打进 dist/,安装即用。
  • 样式策略:见下文「样式」一节,含 Mako 类 CSS 解析器宿主的运行时注入逃生路。

安装

npm i @gantfdt/office-sdk   # 宿主需已有 react 18 / react-dom 18

要求 Node ≥ 20(构建侧);浏览器产物 target es2020。

入口一览(exports 子路径)

| 子路径 | 内容 | 说明 | | ----------------- | ------------------------------------------------------------ | ------------------------------------------------- | | . | createOffice / 会话 / 能力矩阵 / 日志与错误模型 / 下载工具 | 无头一体化门面 | | ./react | useOfficeSession、usePresentationEditor 等 React 绑定 | | | ./univer | UniverWorkbench / createUniverEngine / disposeEngine | 文档/表格/演示引擎与工作台画布 | | ./pdf | GPdf / convertPdf | PDF 解析与转换(无头) | | ./pdf/ui | GPdfViewer | PDF canvas 查看器(样式内联在 JS,无需外部 css) | | ./pdf/worker | pdf.worker.min.mjs 文件路径 | 与内联 pdfjs同版本配对,仅供自托管该文件时使用 | | ./pdf/worker-text | pdfWorkerText 字符串导出 | 随包 worker 源码,SDK 内部用它造 blob worker;宿主一般不直接用 | | ./workspace | WorkspaceShell / Ribbon / 配置 hooks / 功能开关 | 编辑器工作台 UI | | ./workspace/pdf | PdfWorkspace / PdfRibbon / usePdfWorkspace | PDF 工作台 | | ./styles.css | GantOffice 工作台自有样式 | 静态 css 子路径 | | ./univer.css | Univer 引擎样式 | 用 ./univer、./workspace 时需宿主显式引入 | | ./styles-text | stylesCss / univerCss / allCssText 字符串导出 | Mako 类宿主运行时注入用 |

快速上手

Excel/DOCX/PPTX 预览或编辑(保留宿主自己的弹窗/页面外壳,SDK 无头渲染):

import { UniverWorkbench } from '@gantfdt/office-sdk/univer';
import '@gantfdt/office-sdk/univer.css'; // 引擎样式(Mako 类宿主改用 ./styles-text 注入)
import '@gantfdt/office-sdk/styles.css'; // GantOffice 工作台样式

<UniverWorkbench file={arrayBuffer} fileName="book.xlsx" readOnly />

PDF 预览(worker 随包交付,无需任何 worker 配置):

import { GPdf } from '@gantfdt/office-sdk/pdf';
import { GPdfViewer } from '@gantfdt/office-sdk/pdf/ui';

const pdf = await GPdf.open(uint8Array, { name: 'contract.pdf' });
const viewer = new GPdfViewer({ container, pdf }); // container: HTMLElement
await viewer.mount();

页面有 CSP 且不放行 blob: worker 时,钉一个同源 worker 文件即可(详见下节):

import { setWorkerSrc } from '@gantfdt/office-sdk/pdf';
setWorkerSrc('/js/pdf.worker.min.mjs'); // 文件取自 ./pdf/worker,拷进宿主静态目录

需要工作台外壳(Ribbon/面板/功能开关)时用 ./workspace 的 WorkspaceShell,preset="viewer" | "import" | "full",或 features={{ save: false }} 精细裁剪。

样式(务必读一次)

  1. 正常宿主(webpack / rspack / vite / esbuild):显式引两份 css——import '@gantfdt/office-sdk/univer.css'(Univer 引擎样式)与 import '@gantfdt/office-sdk/styles.css'(工作台)。入口 JS 刻意不带 css 副作用 import:一旦带上,下面第 2 类宿主就没有逃生路了。

  2. univer.css 是并集:SDK 自有样式 + 构建期从 @univerjs/preset-sheets-core、@univerjs/ui 等依赖收编进来的引擎样式(引擎规则在前、SDK 规则在后,保持与宿主现有层叠一致),bundle 内不残留任何 @univerjs/**.css 导入。post-build 末尾有完整性守卫——任何一条源规则在最终 univer.css 里消失就直接 exit 1,防止「收编变成覆盖写」把 SDK 自有规则(.dark: / .rtl: / 任意值宽度那一类)整片抹掉。因此宿主侧那些「安装后剥掉 Tailwind 转义规则」的后处理脚本(例如某些仓库的 fix-univer-css postinstall)碰不到它,也不会再引发 Univer 布局坍塌。

  3. Mako 类 Rust CSS 解析器宿主(解析不了 Tailwind 任意值转义选择器 \[ \] \",会直接报错):不要静态引 css 子路径,改用运行时字符串注入——

    import { allCssText } from '@gantfdt/office-sdk/styles-text';
    const el = document.createElement('style');
    el.textContent = allCssText;
    document.head.appendChild(el);
  4. 严禁对 SDK 样式做规则删减/“瘦身”:Tailwind 转义选择器是 Univer 主布局(grid 列定义等)的一部分,剥规则 = 表格布局坍塌(实测事故)。样式原文零删减随包分发。

PDF worker:随包交付(1.3.0 起零配置)

打开 PDF 时 worker 按四级优先级解析,命中即停:

  1. 本次调用的 workerSrc(GPdf.open / GPdfViewer / PdfWorkspace / printPdfBytes 都有);
  2. setWorkerSrc(url) 注册的进程级默认值;
  3. 用随包 worker 文本(./pdf/worker-text)现造的 blob: module worker——默认就走这一级,宿主既不用拷文件也不用配 bundler 资源规则;
  4. 空串:不去动 GlobalWorkerOptions.workerSrc。这一级只在 Node(批量转换、构建期预转换)有意义,浏览器里它是硬失败,见下。

随包文本那条 import('@gantfdt/office-sdk/pdf/worker-text') 刻意保持字面量动态 import 且不在构建期解析,宿主打包器(webpack / rspack / Mako / vite)把它切成异步 chunk:只有真的打开 PDF 才下载。实测 12 页样例页:走 blob 时该 chunk 传输 418KB(原文 1.42MB,服务端 gzip),走 setWorkerSrc 时传输 0B。post-build 有字节守卫——dist/worker-text.js 与 dist/pdf.worker.min.mjs 逐字节一致才允许出包,所以它永远与 dist 里内联的 pdfjs 主线程同版本配对(本批 pdfjs 4.10.38),不要混用宿主 node_modules 里其他版本的 worker。

worker 的这份状态放在 globalThis 的 Symbol.for('@gant/pdf-sdk.worker') 袋子里,不是模块变量:三个 pdf 入口各自内联一份 SDK,模块作用域互不相通,只有共享袋子才能保证「在 ./pdf 里钉的地址,./pdf/ui 与 ./workspace/pdf 同样认」。

CSP 实测矩阵

12 页样例 PDF,五种配置下渲染结果完全一致(12 页 / 12 canvas / 同一 26731 个着墨像素),差别只在 worker 落在哪:

| CSP 现场 | 宿主配置 | 实际用的 worker | 结果 | | -------- | -------- | --------------- | ---- | | 无 | 不配置 | 2× blob: module worker | 正常,open 78ms / mount 215ms | | worker-src 'self'; script-src 'self' blob: | 不配置 | worker 被拦,pdf.js 改 import() 同源文本 | 正常,解析退回主线程(小文件无感,大文件变慢) | | worker-src 'self'; script-src 'self' | 不配置 | worker 与兜底 import() 双双被拦 | 失败:Setting up fake worker failed: "Failed to fetch dynamically imported module: blob:…" | | worker-src 'self'; script-src 'self' | setWorkerSrc('/js/pdf.worker.min.mjs') | 2× 同源 module worker | 正常,open 68ms / mount 201ms,且不下载 worker 文本 chunk | | 同上 | 每次调用传 workerSrc | 2× 同源 module worker | 正常,open 72ms / mount 229ms |

要点:

  • worker-src 'self' 不覆盖 blob:,default-src 同理。所以只要现场 CSP 卡了 blob:,就必须走同源文件(setWorkerSrc 或逐次 workerSrc)——这条就是「A 方案」的老做法,随时可用,优先级还更高。
  • new Worker(blob:) 被 CSP 拦时不会同步抛错(违规是异步上报的),SDK 无法提前探测,只能交给 pdf.js 退主线程;因此「能不能兜住」取决于 script-src 放不放行 blob:,上表第三行就是两者都不放行的死局。
  • 别混着配。GlobalWorkerOptions.workerSrc 是全局唯一值,一处传了同源地址、另一处不传,不传那处会把全局覆盖成 blob:,严格 CSP 下连原本能用的文档也一起失败——用 setWorkerSrc 一次钉死就不会有这种漂移。
  • 完全取消随包 worker(setWorkerTextLoader(null) 且不传 workerSrc)在浏览器里是硬失败,pdf.js 报 No "GlobalWorkerOptions.workerSrc" specified.;主线程兜底只对 Node 成立。SDK 此时会 console.warn 一次点名这条错误。
  • 长时间运行、反复开合预览的页面可以调 disposeWorkerSrc() 回收已造的 blob URL。

体积与按需引入

多入口各自完整自包含(tsup splitting: false,无共享 chunk)——这是「宿主只装一个包、引一个入口即可用」的代价与取舍:

| 入口 | 体积(min 后) | | ------------------------------------------- | -------------- | | index.js / univer.js | ~12 MB | | workspace.js / workspace-pdf.js | ~6–7 MB | | pdf.js | ~0.9 MB | | react.js / pdf-ui.js / styles-text.js | <0.5 MB | | worker-text.js(PDF 异步 chunk) | ~1.4 MB(不打开 PDF 就不下载) | | 全包 tarball | ~9.8 MB |

  • 同一宿主建议只引一个主入口:文档/表格/演示场景选 ./workspace(或无头 . / 画布 ./univer),PDF 场景选 ./pdf + ./pdf/ui。多入口同时静态引入不会报错(@univerjs/* 为 external 共享同一份,无双实例风险),但打进各自 dist 的 pdfjs / xlsx / jszip 等引擎与内部装配代码会被重复下载与执行,浪费带宽与内存,且各入口的 Univer preset 装配代码会重复注册,控制台出现大量 Identifier … already exists 提示(Univer 幂等降级,不影响功能)。
  • 需要多个能力域时优先动态 import()(路由级按需加载),或按官方 dist sizes 打印评估取舍。
  • 精确数字以 npm run build -w @gantfdt/office-sdk 结束打印的 dist sizes 为准。

版本与升级

  • 本包与内部 @gant-office/* 系列同仓同批发布(统一版本号)。
  • @univerjs/* 精确锁版是刻意的:bundle 与类型图按该版本构建,semver 范围会引入不可复现的类型/运行时漂移。
  • 升级 = 升级本包一个动作;无需单独动 react(peer)或 pdfjs(已内联)。
  • 宿主 tsconfig 请保持 skipLibCheck: true(社区默认)。Univer 1.0.4 自身 d.ts 在 skipLibCheck: false 下会报其内部类型错(缺 @types/async-lock 等),与本包无关;本包 d.ts 自身在两种模式下均无悬空引用。

来源

源码仓库:https://codeup.aliyun.com/gant/GantLabs/gant-office(sdk/office-sdk,其余能力实现见同仓库 sdk/* 内部包,构建时全部内联进本包 dist)。