Skip to content

Node.js-Bibliothek für Office — Schnellstart

Das npm-Paket office-oxide ist die native Node.js-Bindung: über koffi wird liboffice_oxide dynamisch geladen, und es gibt eine schlanke, idiomatische JavaScript-API. Schneller und kleiner als der WebAssembly-Build, liefert aber plattformspezifische Prebuilds statt einer portablen Binärdatei.

Brauchst du ein einziges Artefakt, das im Browser, in Bundlern oder in Node ohne native Libs läuft, nimm stattdessen office-oxide-wasm.

Installation

npm install office-oxide

Beim postinstall sucht das Paket nach einem passenden Prebuild unter node_modules/office-oxide/prebuilds/<platform>-<arch>/. Wenn keiner vorhanden ist, konfiguriere vor der ersten Nutzung eine der folgenden Optionen:

  1. OFFICE_OXIDE_LIB — absoluter Pfad zur Bibliothek (z. B. /opt/office_oxide/liboffice_oxide.so).
  2. Prebuild-Verzeichnis — leg die Bibliothek in prebuilds/<platform>-<arch>/ (z. B. linux-x64, darwin-arm64, win32-x64) im Paket ab.
  3. System-Bibliothekspfad — installiere so, dass LD_LIBRARY_PATH / DYLD_LIBRARY_PATH / PATH sie findet.

Läuft auf Node 18+.

Ein Dokument lesen

import { Document } from 'office-oxide';

const doc = Document.open('report.docx');
try {
  console.log(doc.plainText());
} finally {
  doc.close();
}

Oder mit TC39 Explicit Resource Management (Node 22+):

import { Document } from 'office-oxide';

using doc = Document.open('report.docx');
console.log(doc.plainText());
// doc.close() läuft beim Verlassen des Scopes automatisch

Einzelaufruf-Helfer:

import { extractText } from 'office-oxide';
console.log(extractText('report.docx'));

Kern-API

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();           // bereits geparstes Objekt

  doc.saveAs('file.docx');         // Zielformat aus der Erweiterung
} finally {
  doc.close();
}

Aus rohen Bytes (Uint8Array oder 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 muss 'docx' | 'xlsx' | 'pptx' | 'doc' | 'xls' | 'ppt' sein.

Modul-Helfer:

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"

Bearbeiten

Editierbare Handles bewahren beim Speichern alle unveränderten OPC-Teile. Nur DOCX, XLSX und PPTX.

import { EditableDocument } from 'office-oxide';

using ed = EditableDocument.open('template.docx');
const n = ed.replaceText('{{name}}', 'Alice');
console.log(`${n} Ersetzungen`);
ed.save('out.docx');

XLSX-Zellen setzen

import { EditableDocument } from 'office-oxide';

using wb = EditableDocument.open('budget.xlsx');

wb.setCell(0, 'A1', 'Total');   // String
wb.setCell(0, 'B1', 42.5);      // Zahl
wb.setCell(0, 'C1', true);      // Boolean
wb.setCell(0, 'D1', null);      // leer

wb.save('budget.xlsx');

sheetIndex ist nullbasiert; cellRef folgt der Standard-Tabellennotation.

Formatunabhängige IR

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

Bytes-Pipelines

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());

Altformate

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(); }

Fehler

Fehler werfen OfficeOxideError mit numerischem code und 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;
  }
}
Code Bedeutung
0 OK
1 ungültiges Argument
2 IO-Fehler
3 Parsing-Fehler
4 Extraktionsfehler
5 interner Fehler
6 nicht unterstütztes Format

Fehlersuche

Symptom Lösung
office-oxide: failed to load native library OFFICE_OXIDE_LIB auf einen absoluten Pfad setzen oder einen passenden Prebuild ins Paket legen.
koffi: ABI mismatch Prebuild passt nicht zu Plattform/Arch des Node-Prozesses — neu installieren oder frischen holen.
TypeError: data must be a Uint8Array or Buffer Document.fromBytes akzeptiert nur Binärtypen. Buffer.from(base64, 'base64') nutzen.
Document is closed Methode nach close() oder nach Verlassen eines using-Scopes aufgerufen. Frisches Handle öffnen.
Legacy .doc öffnet, zeigt aber Müll Verschlüsselte Word-97-Dokumente werden nicht entschlüsselt — vorher mit LibreOffice entschlüsseln.

Siehe auch