Silurus/ooxml: 像素忠实的Office文档,浏览器中呈现
这个完整的代码库——Rust解析器、TypeScript渲染器、测试和工具——是通过Claude(Anthropic的AI助手)通过迭代提示实现的。该仓库中没有人类编写的应用程序代码。演示(Storybook)一个基于浏览器的Office Open XML文档查看器,渲染到HTML Canvas元素。解析器用Rust编写并编译为WebAssembly;渲染器使用Canvas 2D API。每种格式还提供一个无头引擎(DocxDocument / XlsxWorkbook / PptxPresentation),可渲染到任何调用者提供的画布中,因此你可以组合自己的用户界面——滚动视图、缩略图网格、主细节窗格——而不是被锁定在内置查看器中。请参见Storybook演示中的示例部分。DOCX XLSX PPTX npm install @silurus/ooxml # 或 pnpm add @silurus/ooxml 捆绑工具注意:该包嵌入了.wasm文件。使用Vite时添加vite-plugin-wasm;使用webpack时使用experiments.asyncWebAssembly。捆绑大小注意:该包仅支持ESM(.mjs)。npm的未打包大小将所有四个入口捆绑包相加,包括可选择的数学引擎(MathJax + STIX Two Math,约3 MB)。实际落入你应用程序中的文件要小得多——仅导入你需要的格式(例如@silurus/ooxml/pptx)。数学引擎是一个单独的条目(@silurus/ooxml/math):只有当你导入它并将其传递给查看器时,它才会被捆绑(见渲染方程式)。从未接收数学引擎的查看器——以及所有xlsx的使用——都会完全树摇掉约3 MB。快速开始导入 { DocxViewer } 来自 '@silurus/ooxml/docx' ; 导入 { XlsxViewer } 来自 '@silurus/ooxml/xlsx' ; 导入 { PptxViewer } 来自 '@silurus/ooxml/pptx' ; // DOCX — 调用者提供 <canvas> const canvas = document.getElementById('docx-canvas') as HTMLCanvasElement ; const docx = new DocxViewer(canvas) ; await docx.load('/document.docx') ; docx.nextPage(); // XLSX — 查看器管理自己的 <canvas> + 选项卡条 const container = document.getElementById('xlsx-container') as HTMLElement ; const xlsx = new XlsxViewer(container) ; await xlsx.load('/workbook.xlsx'); // PPTX — 调用者提供 <canvas> const canvas = document.getElementById('pptx-canvas') as HTMLCanvasElement ; const pptx = new PptxViewer(canvas) ; await pptx.load('/deck.pptx'); pptx.nextSlide(); 渲染方程式OMML方程(m:oMath / m:oMathPara)在.docx /.pptx中使用MathJax + STIX Two Math进行渲染。该引擎约为3 MB,因此是可选择的:从单独的@silurus/ooxml/math条目中导入数学引擎并将其传递给查看器。传递它,方程式将渲染;省略它,系统将不再引用该引擎,因此捆绑器会完全将约3 MB树摇掉(方程式会被简单跳过)。它是完全自包含的:没有网络,没有跨域请求。导入 { DocxViewer } 来自 '@silurus/ooxml/docx' ; 导入 { math } 来自 '@silurus/ooxml/math' ; const canvas = document.getElementById('docx-canvas') as HTMLCanvasElement ; const docx = new DocxViewer(canvas, { math }) ; // ← 方程式现在渲染 await docx.load('/paper-with-equations.docx') ; 同样的数学引擎适用于PptxViewer和无头DocxDocument / PptxPresentation API(在其选项中接受数学)。xlsx没有方程式支持,并且从不引用该引擎。架构图流程图 TB subgraph build["🦀 构建时间(Rust → WebAssembly)"] direction LR docx_rs["packages/docx/parser/src/lib.rs"] xlsx_rs["packages/xlsx/parser/src/lib.rs"] pptx_rs["packages/pptx/parser/src/lib.rs"] docx_rs -- wasm-pack --> docx_wasm["docx_parser.wasm"] xlsx_rs -- wasm-pack --> xlsx_wasm["xlsx_parser.wasm"] pptx_rs -- wasm-pack --> pptx_wasm["pptx_parser.wasm"] end subgraph browser["🌐 运行时(浏览器)"] subgraph core_pkg["@silurus/ooxml-core(共享基本元素)"] CORE["renderChart · resolveFill · applyStroke buildCustomPath · autoResize · 共享类型"] end subgraph docx_pkg["@silurus/ooxml · docx"] DV["DocxViewer"] --> DD["DocxDocument"] DD --> DW["worker.ts 〈Web Worker — 仅解析〉"] DD --> DR["renderer.ts 〈Canvas 2D — 主线程〉"] end subgraph xlsx_pkg["@silurus/ooxml · xlsx"] XV["XlsxViewer"] --> XB["XlsxWorkbook"] XB --> XW["worker.ts 〈Web Worker — 仅解析〉"] XB --> XR["renderer.ts 〈Canvas 2D — 主线程〉"] end subgraph pptx_pkg["@silurus/ooxml · pptx"] PV["PptxViewer"] --> PP["PptxPresentation"] PP --> PW["worker.ts 〈Web Worker — 仅解析〉"] PP --> PR["renderer.ts 〈Canvas 2D — 主线程〉"] end DR -. uses .-> CORE XR -. uses .-> CORE PR -. uses .-> CORE end docx_wasm --> DW xlsx_wasm --> XW pptx_wasm --> PW DR --> canvas["<canvas>"] XR --> canvas PR --> canvas 加载这三种格式遵循相同的形状:工人通过WASM解析.docx / .xlsx / .pptx存档并将JSON模型发送回主线程,在主线程中渲染器绘制在画布上。渲染保持在主线程上,因此画布共享该文档的FontFaceSet——在工作线程中的OffscreenCanvas有自己的字体注册表,会默默地失败。
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡