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-glue для кожного підшляху. Імпорт із кореня автоматично підхоплює 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