Skip to content

PDF Oxide (WASM) 시작하기

PDF Oxide는 WebAssembly로 컴파일되어 브라우저, Deno, Bun, 그리고 Cloudflare Workers와 Vercel Edge 같은 엣지 런타임에서 실행됩니다. Python·Rust·Node.js·Go·C# 바인딩을 구동하는 동일한 Rust 코어가 JavaScript 환경에서도 네이티브에 가까운 성능으로 동작합니다.

Node.js를 사용하나요? 서버 사이드에서는 네이티브 N-API 애드온 pdf-oxide를 권장합니다. 더 빠르고 OCR, 렌더링, 서명까지 지원합니다. 이 페이지의 WASM 빌드는 네이티브 애드온을 올릴 수 없는 브라우저와 엣지 런타임에 적합합니다.

설치

npm install pdf-oxide-wasm
import { WasmPdfDocument, WasmPdf } from "pdf-oxide-wasm";

빠른 시작

Node.js

import { readFileSync } from "fs";
import { WasmPdfDocument } from "pdf-oxide-wasm";

const bytes = new Uint8Array(readFileSync("document.pdf"));
const doc = new WasmPdfDocument(bytes);

console.log(`Pages: ${doc.pageCount()}`);
console.log(doc.extractText(0));

doc.free();

브라우저

<script type="module">
import init, { WasmPdfDocument } from "pdf-oxide-wasm";

await init();

const response = await fetch("document.pdf");
const bytes = new Uint8Array(await response.arrayBuffer());
const doc = new WasmPdfDocument(bytes);

console.log(`Pages: ${doc.pageCount()}`);
console.log(doc.extractText(0));
doc.free();
</script>

파일 입력이 있는 브라우저

<input type="file" id="pdfInput" accept=".pdf" />
<pre id="output"></pre>

<script type="module">
import init, { WasmPdfDocument } from "pdf-oxide-wasm";
await init();

document.getElementById("pdfInput").addEventListener("change", async (e) => {
  const file = e.target.files[0];
  const bytes = new Uint8Array(await file.arrayBuffer());
  const doc = new WasmPdfDocument(bytes);

  let result = `Pages: ${doc.pageCount()}\n\n`;
  for (let i = 0; i < doc.pageCount(); i++) {
    result += `--- Page ${i + 1} ---\n`;
    result += doc.extractText(i) + "\n\n";
  }

  document.getElementById("output").textContent = result;
  doc.free();
});
</script>

텍스트 추출

단일 페이지

const doc = new WasmPdfDocument(bytes);
const text = doc.extractText(0);

전체 페이지

const allText = doc.extractAllText();

구조화 추출

위치와 폰트 메타데이터가 포함된 문자·스팬 단위 데이터를 얻을 수 있습니다.

// 문자 단위 데이터
const chars = doc.extractChars(0);
for (const c of chars) {
  console.log(`'${c.char}' at (${c.bbox.x}, ${c.bbox.y}) font=${c.fontName}`);
}

// 스팬 단위 데이터
const spans = doc.extractSpans(0);
for (const span of spans) {
  console.log(`"${span.text}" size=${span.fontSize}`);
}

Markdown 변환

const markdown = doc.toMarkdown(0);

// 옵션 지정
const md = doc.toMarkdown(0, true, true); // detect_headings, include_images

// 전체 페이지
const allMarkdown = doc.toMarkdownAll();

HTML 변환

const html = doc.toHtml(0);

// 전체 페이지
const allHtml = doc.toHtmlAll();

PDF 생성

Markdown, HTML, 일반 텍스트로부터 새 PDF를 WasmPdf로 만들 수 있습니다.

import { WasmPdf } from "pdf-oxide-wasm";

// Markdown에서 생성
const pdf = WasmPdf.fromMarkdown("# Hello World\n\nThis is a PDF.");
const pdfBytes = pdf.toBytes(); // Uint8Array

// HTML에서 생성
const invoice = WasmPdf.fromHtml("<h1>Invoice</h1><p>Amount: $42</p>");

// 일반 텍스트에서 생성
const notes = WasmPdf.fromText("Plain text content.");

// 파일로 저장 (Node.js)
import { writeFileSync } from "fs";
writeFileSync("output.pdf", pdf.toBytes());

폼 필드

const fields = doc.getFormFields();
for (const f of fields) {
  console.log(`${f.name} (${f.fieldType}) = ${f.value}`);
}

// 폼 데이터 내보내기
const fdfBytes = doc.exportFormData();        // FDF 형식
const xfdfBytes = doc.exportFormData("xfdf"); // XFDF 형식

검색

// 전체 페이지에서 검색
const results = doc.search("configuration", true); // case_insensitive
for (const r of results) {
  console.log(`Found "${r.text}" on page ${r.page}`);
}

// 단일 페이지에서 검색
const pageResults = doc.searchPage(0, "configuration", true);

바이트에서 열기

WasmPdfDocument 생성자가 이미 Uint8Array를 직접 받기 때문에 별도의 from_bytes 메서드는 필요 없습니다.

// 바로 사용 가능 — WasmPdfDocument는 바이트를 받습니다
const doc = new WasmPdfDocument(uint8Array);

암호화된 PDF

const doc = new WasmPdfDocument(encryptedBytes);
const success = doc.authenticate("password");
if (success) {
  console.log(doc.extractText(0));
}

편집

const doc = new WasmPdfDocument(bytes);

// 메타데이터
doc.setTitle("Updated Title");
doc.setAuthor("Jane Doe");

// 페이지 회전
doc.rotatePage(0, 90);

// 변경 사항을 저장
const edited = doc.save();

// 암호화하여 저장
const encrypted = doc.saveEncryptedToBytes(
  "user-password",
  "owner-password",
  true,   // allow_print
  true,   // allow_copy
  false,  // allow_modify
  true    // allow_annotate
);

메모리 관리

WASM 객체는 Rust 메모리를 보유하므로 명시적으로 해제해야 합니다.

const doc = new WasmPdfDocument(bytes);
try {
  const text = doc.extractText(0);
} finally {
  doc.free();
}

기능 지원 현황

일부 기능은 네이티브 의존성이 필요하여 WebAssembly 빌드에서는 사용할 수 없습니다.

기능 WASM 비고
텍스트 추출 지원 완전 지원
PDF 생성 지원 Markdown, HTML, 텍스트
PDF 편집 지원 완전 지원
암호화 지원 AES-256
OCR 미지원 네이티브 ONNX Runtime 필요
디지털 서명 미지원 네이티브 암호화 라이브러리 필요
페이지 렌더링 미지원 네이티브 tiny-skia 필요

OCR이나 렌더링이 필요하다면 Python 또는 Rust 바인딩을 사용하세요.

다음 단계