Skip to content

WASM Office 库 — 快速上手

office-oxide-wasm 包是 office_oxide 的 WebAssembly 编译产物。零原生依赖、单一 Rust 内核二进制,三种子路径入口让它在任何 JavaScript 运行环境中都能跑 — 浏览器、Node.js,以及 Vite、Webpack、Rollup 等打包工具。

如果在 Node.js 中不想要 WASM 开销,请改用原生 office-oxide

安装

npm install office-oxide-wasm

无 postinstall。支持 Node 18+、所有支持 WebAssembly 的现代浏览器,以及任何带 ES 模块 / CommonJS 加载器的环境。

子路径导出

导入路径 目标 格式
office-oxide-wasm(默认) 面向打包工具的 ESM(Vite、Webpack、Rollup) ESM
office-oxide-wasm/node Node.js CommonJS
office-oxide-wasm/web 通过 <script type="module">import 的浏览器 ESM,需要 init()

按你的运行时选择对应版本。

读取文档

打包工具(ESM)

import { WasmDocument } from 'office-oxide-wasm';

const res = await fetch('/report.docx');
const data = new Uint8Array(await res.arrayBuffer());
const doc = new WasmDocument(data, 'docx');
try {
  console.log(doc.plainText());
} finally {
  doc.free();
}

Node.js(CJS)

const { readFileSync } = require('node:fs');
const { WasmDocument } = require('office-oxide-wasm/node');

const data = readFileSync('report.docx');
const doc = new WasmDocument(data, 'docx');
try {
  console.log(doc.plainText());
} finally {
  doc.free();
}

浏览器(无打包工具)

<script type="module">
  import init, { WasmDocument } from 'https://cdn.jsdelivr.net/npm/office-oxide-wasm/web/office_oxide.js';
  await init();

  const res = await fetch('/report.docx');
  const data = new Uint8Array(await res.arrayBuffer());
  const doc = new WasmDocument(data, 'docx');
  try {
    document.body.textContent = doc.plainText();
  } finally {
    doc.free();
  }
</script>

仅限浏览器: 构造 WasmDocument 之前必须 await init()。Node 和打包工具入口会在内部处理初始化。

核心 API

WasmDocument 是唯一的句柄 — WASM 构建中没有 Document / EditableDocument 之分(编辑功能在原生绑定中)。

import { WasmDocument } from 'office-oxide-wasm';

const doc = new WasmDocument(bytes, 'xlsx');
try {
  console.log(doc.formatName());   // "xlsx"
  console.log(doc.plainText());
  console.log(doc.toMarkdown());
  console.log(doc.toHtml());
  const ir = doc.toIr();           // 解析后的对象
} finally {
  doc.free();   // 必须 — WASM 内存不受 GC 管理
}

所有方法均为 camelCase: plainTexttoMarkdowntoHtmltoIrformatNamebytes 必须是 Uint8Arrayformat 必须是 'docx' | 'xlsx' | 'pptx' | 'doc' | 'xls' | 'ppt' 之一。

旧版二进制格式(docxlsppt)也能在 WASM 中解析。

编辑(WASM 不支持)

EditableDocument — 文本替换与单元格写入 — 在 WASM 构建中未暴露。需要编辑请使用:

只读的文本 / Markdown / HTML / IR 工作流,WASM 功能完整。

与格式无关的 IR

const doc = new WasmDocument(bytes, 'docx');
const ir = doc.toIr();
doc.free();

for (const section of ir.sections) {
  console.log(section.title);
  for (const el of section.elements) {
    // el.kind: "Heading" | "Paragraph" | "Table" | "List" | "Image" | ...
  }
}

IR 架构与 Rust 的 DocumentIR 完全一致,因此服务端和客户端管道可以共用同一个处理器。

字节进、字节出

WASM 构建只接受字节输入 — 没有文件 I/O 接口。

// 来自 <input type="file">
const file = inputEl.files[0];
const data = new Uint8Array(await file.arrayBuffer());
const doc = new WasmDocument(data, file.name.split('.').pop().toLowerCase());

// 来自 fetch
const res = await fetch(url);
const data = new Uint8Array(await res.arrayBuffer());

// 在 Node
const data = new Uint8Array(require('node:fs').readFileSync('file.docx'));

打包工具

// Vite — 通常零配置
import { WasmDocument } from 'office-oxide-wasm';

// Webpack 5 — 添加到 module.rules:
//   { test: /\.wasm$/, type: 'asset/resource' }

TypeScript

类型定义(office_oxide.d.ts)随每个子路径导出的 JS 胶水一起发布。从根路径导入会自动用到打包工具版的类型;import type { WasmDocument } from 'office-oxide-wasm/node' 也可以。

内存管理

const doc = new WasmDocument(bytes, 'docx');
try {
  // ... 工作
} finally {
  doc.free();
}

忘记调用 free() 会让 WASM 内存一直泄漏,直到实例被销毁。

错误

失败以普通 Error 实例的形式抛出,附带描述性消息。因为 WASM 构建使用 JsValue::from_str,错误码不会以数字形式暴露 — 请检查消息字符串。

故障排查

症状 解决
ReferenceError: WebAssembly is not defined 目标环境不支持 WASM。改用原生 office-oxide
浏览器: TypeError: ... before init() office-oxide-wasm/web 时忘了 await init()
打包工具抱怨 .wasm 添加 WASM 资源规则,或把目标切到 esnext
unsupported format: pdf 仅接受六种格式: docxxlsxpptxdocxlsppt
热循环里内存无限增长 没有在迭代之间调用 doc.free()

相关链接