Biblioteca Office para Node.js — Inicio Rápido
El paquete npm office-oxide es el binding nativo para Node.js: carga dinámicamente liboffice_oxide mediante koffi y expone una API JavaScript pequeña e idiomática. Más rápido y compacto que el build WebAssembly, pero distribuye prebuilds específicos por plataforma en lugar de un único binario portátil.
Si necesitas un solo artefacto que corra en navegadores, bundlers o Node sin librerías nativas, usa
office-oxide-wasm.
Instalación
npm install office-oxide
En postinstall, el paquete busca un prebuild compatible en node_modules/office-oxide/prebuilds/<platform>-<arch>/. Si no aparece, configura antes del primer uso una de estas opciones:
OFFICE_OXIDE_LIB— ruta absoluta a la librería (por ejemplo/opt/office_oxide/liboffice_oxide.so).- Directorio de prebuilds — coloca la librería en
prebuilds/<platform>-<arch>/(por ejemplolinux-x64,darwin-arm64,win32-x64) dentro del paquete. - Ruta de librerías del sistema — instálala donde
LD_LIBRARY_PATH/DYLD_LIBRARY_PATH/PATHpuedan encontrarla.
Funciona en Node 18+.
Leer un documento
import { Document } from 'office-oxide';
const doc = Document.open('report.docx');
try {
console.log(doc.plainText());
} finally {
doc.close();
}
O con TC39 explicit resource management (Node 22+):
import { Document } from 'office-oxide';
using doc = Document.open('report.docx');
console.log(doc.plainText());
// doc.close() se llama automáticamente al salir del ámbito
Helper de un solo paso:
import { extractText } from 'office-oxide';
console.log(extractText('report.docx'));
API principal
import { Document } from 'office-oxide';
const doc = Document.open('file.xlsx');
try {
console.log(doc.format); // "xlsx"
console.log(doc.plainText());
console.log(doc.toMarkdown());
console.log(doc.toHtml());
const ir = doc.toIr(); // objeto ya parseado
doc.saveAs('file.docx'); // formato destino inferido por la extensión
} finally {
doc.close();
}
Desde bytes en bruto (Uint8Array o Buffer):
import { readFileSync } from 'node:fs';
import { Document } from 'office-oxide';
const data = readFileSync('report.pptx');
using doc = Document.fromBytes(data, 'pptx');
console.log(doc.toMarkdown());
format debe ser 'docx' | 'xlsx' | 'pptx' | 'doc' | 'xls' | 'ppt'.
Helpers a nivel de módulo:
import { extractText, toMarkdown, toHtml, detectFormat, version } from 'office-oxide';
extractText('file.docx'); // string
toMarkdown('file.pptx'); // string
toHtml('file.xlsx'); // string
detectFormat('mystery.bin'); // "docx" | ... | null
version(); // "0.1.0"
Edición
Los handles editables conservan al guardar todas las partes OPC sin tocar. Solo DOCX, XLSX y PPTX.
import { EditableDocument } from 'office-oxide';
using ed = EditableDocument.open('template.docx');
const n = ed.replaceText('{{name}}', 'Alice');
console.log(`${n} reemplazos`);
ed.save('out.docx');
Establecer celdas XLSX
import { EditableDocument } from 'office-oxide';
using wb = EditableDocument.open('budget.xlsx');
wb.setCell(0, 'A1', 'Total'); // cadena
wb.setCell(0, 'B1', 42.5); // número
wb.setCell(0, 'C1', true); // booleano
wb.setCell(0, 'D1', null); // vacío
wb.save('budget.xlsx');
sheetIndex empieza en cero; cellRef sigue la notación estándar.
IR independiente del formato
using doc = Document.open('report.docx');
const ir = doc.toIr();
for (const section of ir.sections) {
console.log(section.title);
for (const el of section.elements) {
// el.kind: "Heading" | "Paragraph" | "Table" | "List" | ...
}
}
Pipelines basados en bytes
import { Document } from 'office-oxide';
const res = await fetch('https://example.com/report.docx');
const data = new Uint8Array(await res.arrayBuffer());
using doc = Document.fromBytes(data, 'docx');
console.log(doc.toMarkdown());
Formatos heredados
using doc = Document.open('old.xls');
doc.saveAs('modern.xlsx');
CommonJS
const { Document } = require('office-oxide');
const doc = Document.open('file.docx');
try { console.log(doc.plainText()); } finally { doc.close(); }
Errores
Los fallos lanzan OfficeOxideError con code numérico y operation:
import { Document, OfficeOxideError } from 'office-oxide';
try {
using doc = Document.open('missing.docx');
} catch (e) {
if (e instanceof OfficeOxideError) {
console.error(`code=${e.code} op=${e.operation}`);
} else {
throw e;
}
}
| Código | Significado |
|---|---|
| 0 | OK |
| 1 | argumento inválido |
| 2 | error de IO |
| 3 | error de parseo |
| 4 | falló la extracción |
| 5 | error interno |
| 6 | formato no soportado |
Solución de problemas
| Síntoma | Solución |
|---|---|
office-oxide: failed to load native library |
Pon OFFICE_OXIDE_LIB con la ruta absoluta o coloca un prebuild válido en el paquete. |
koffi: ABI mismatch |
El prebuild no coincide con la plataforma/arquitectura del proceso Node — reinstala o trae uno nuevo. |
TypeError: data must be a Uint8Array or Buffer |
Document.fromBytes solo acepta tipos binarios. Usa Buffer.from(base64, 'base64'). |
Document is closed |
Llamaste a un método tras close() o tras salir de un using. Abre un handle nuevo. |
.doc heredado abre, pero se ve corrupto |
Los Word 97 cifrados no se descifran — descífralo antes con LibreOffice. |
Véase también
- Build WASM — un único binario portátil, corre en navegadores y bundlers
- Benchmarks de rendimiento
- Paquete en npm