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();
}
Navegador (sin bundler)
<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 unWasmDocument. 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:
- Binding nativo para Node (
office-oxide) - Binding Python
- Binding .NET
- Crate Rust
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
- Binding nativo para Node — más rápido, con edición
- Benchmarks de rendimiento
- Paquete en npm