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 (по умолчанию) |
Bundler-friendly ESM (Vite, Webpack, Rollup) | ESM |
office-oxide-wasm/node |
Node.js | CommonJS |
office-oxide-wasm/web |
Браузеры через <script type="module"> или import |
ESM, нужен init() |
Берите вариант под свой рантайм.
Прочитать документ
Bundler (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- и bundler-входы инициализируются сами.
Базовый API
WasmDocument — единственный handle: в 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: plainText, toMarkdown, toHtml, toIr, formatName. bytes должен быть Uint8Array. format — один из 'docx' | 'xlsx' | 'pptx' | 'doc' | 'xls' | 'ppt'.
Legacy-форматы (doc, xls, ppt) тоже парсятся в WASM.
Редактирование (в WASM нет)
EditableDocument — замены текста и запись ячеек — не выставлен в WASM-сборке. Для редактирования используйте:
- Нативную Node-привязку (
office-oxide) - Python-привязку
- .NET-привязку
- Rust-крейт
Для read-only потоков — текст / 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'));
Bundlers
// Vite — обычно без настройки
import { WasmDocument } from 'office-oxide-wasm';
// Webpack 5 — добавьте в module.rules:
// { test: /\.wasm$/, type: 'asset/resource' }
TypeScript
Определения типов (office_oxide.d.ts) поставляются вместе с JS-обёрткой каждого подпути. При импорте из корня автоматически подхватываются bundler-типы; 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() |
Забыли await init() для office-oxide-wasm/web. |
Bundler ругается на .wasm |
Добавьте правило для WASM-ассетов или переключите target бандлера на esnext. |
unsupported format: pdf |
Принимаются только шесть форматов: docx, xlsx, pptx, doc, xls, ppt. |
| Память бесконечно растёт в горячем цикле | Не вызываете doc.free() между итерациями. |
Смотрите также
- Нативная Node-привязка — быстрее, поддерживает редактирование
- Бенчмарки производительности
- Пакет: npm