Thanks to visit codestin.com
Credit goes to pdf.oxide.fyi

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 바인딩을 사용하세요.

다음 단계