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

Дивіться також