Skip to content

Biblioteca Office WASM — Inicio Rápido

El paquete office-oxide-wasm es office_oxide compilado a WebAssembly. Cero dependencias nativas, un único binario del núcleo Rust y tres puntos de entrada por subpath para que funcione donde sea que JavaScript funcione — navegadores, Node.js y bundlers como Vite, Webpack y Rollup.

Para Node.js sin la sobrecarga del WASM, usa el paquete nativo office-oxide.

Instalación

npm install office-oxide-wasm

Sin paso de postinstall. Funciona en Node 18+, navegadores modernos con soporte WebAssembly y cualquier entorno con loader ES module / CommonJS.

Exports por subpath

Ruta de import Destino Formato
office-oxide-wasm (por defecto) ESM amigable a bundlers (Vite, Webpack, Rollup) ESM
office-oxide-wasm/node Node.js CommonJS
office-oxide-wasm/web Navegadores con <script type="module"> o import ESM, requiere init()

Elige la variante que encaje con tu runtime.

Leer un documento

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>

Solo en navegador: debes hacer await init() antes de construir un WasmDocument. Las entradas para Node y bundlers gestionan la inicialización internamente.

API principal

WasmDocument es el único handle — el build WASM no separa Document / EditableDocument (la edición vive en los bindings nativos).

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();           // objeto ya parseado
} finally {
  doc.free();   // obligatorio — la memoria WASM no la gestiona el GC
}

Todos los métodos son camelCase: plainText, toMarkdown, toHtml, toIr, formatName. bytes debe ser un Uint8Array. format debe ser uno de 'docx' | 'xlsx' | 'pptx' | 'doc' | 'xls' | 'ppt'.

Los formatos binarios heredados (doc, xls, ppt) también se parsean en WASM.

Edición (no disponible en WASM)

EditableDocument — sustitución de texto y escritura de celdas — no se expone en el build WASM. Para editar, usa:

Para flujos de solo lectura — texto / Markdown / HTML / IR — el WASM cubre todo.

IR independiente del formato

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" | ...
  }
}

El esquema de IR coincide con la DocumentIR de Rust, así que los pipelines del lado del servidor y del cliente pueden compartir el mismo procesador.

Bytes entran, bytes salen

El build WASM solo acepta bytes — no hay superficie de I/O de archivos.

// De un <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());

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

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

Bundlers

// Vite — normalmente sin configuración
import { WasmDocument } from 'office-oxide-wasm';

// Webpack 5 — añade en module.rules:
//   { test: /\.wasm$/, type: 'asset/resource' }

TypeScript

Las definiciones de tipos (office_oxide.d.ts) acompañan al glue JS de cada subpath. Importar desde la raíz pilla automáticamente los tipos de bundler; import type { WasmDocument } from 'office-oxide-wasm/node' también funciona.

Gestión de memoria

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

Olvidar free() deja escapar la memoria WASM hasta que la instancia se destruye.

Errores

Los fallos aparecen como instancias normales de Error con un mensaje descriptivo. Como el build WASM usa JsValue::from_str, los códigos de error no se exponen numéricamente — revisa la cadena del mensaje.

Solución de problemas

Síntoma Solución
ReferenceError: WebAssembly is not defined El entorno destino no soporta WASM. Usa el paquete nativo office-oxide.
Navegador: TypeError: ... before init() Olvidaste el await init() con office-oxide-wasm/web.
El bundler se queja de .wasm Añade una regla de asset para WASM o cambia el target a esnext.
unsupported format: pdf Solo se aceptan seis formatos: docx, xlsx, pptx, doc, xls, ppt.
La memoria crece sin parar en un bucle caliente No estás llamando a doc.free() entre iteraciones.

Véase también