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 (기본) 번들러 친화적 ESM (Vite, Webpack, Rollup) ESM
office-oxide-wasm/node Node.js CommonJS
office-oxide-wasm/web <script type="module"> 또는 import을 사용하는 브라우저 ESM, init() 필요

런타임에 맞는 변형을 고르세요.

문서 읽기

번들러 (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와 번들러 진입점은 초기화를 내부에서 처리합니다.

핵심 API

WasmDocument가 유일한 핸들입니다 — 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. bytesUint8Array여야 합니다. format'docx' | 'xlsx' | 'pptx' | 'doc' | 'xls' | 'ppt' 중 하나.

레거시 바이너리 형식(doc, xls, ppt)도 WASM에서 파싱됩니다.

편집 (WASM에서는 미지원)

EditableDocument — 텍스트 치환과 셀 쓰기 — 는 WASM 빌드에서 노출되지 않습니다. 편집이 필요하면:

읽기 전용 텍스트 / 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'));

번들러

// Vite — 보통 설정 없음
import { WasmDocument } from 'office-oxide-wasm';

// Webpack 5 — module.rules에 추가:
//   { test: /\.wasm$/, type: 'asset/resource' }

TypeScript

타입 정의(office_oxide.d.ts)는 각 서브패스 익스포트의 JS glue와 함께 배포됩니다. 루트에서 임포트하면 번들러 타입이 자동으로 적용됩니다. 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() office-oxide-wasm/web 사용 시 await init()을 잊었습니다.
번들러가 .wasm에 불평 WASM 자산 규칙을 추가하거나 번들러 타깃을 esnext로 바꾸세요.
unsupported format: pdf 6가지 형식만 받습니다: docx, xlsx, pptx, doc, xls, ppt.
핫 루프에서 메모리가 무한 증가 반복 사이에 doc.free()를 호출하지 않았습니다.

더 보기