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 (по умолчанию) 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-сборке. Для редактирования используйте:

Для 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() между итерациями.

Смотрите также