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 바인딩을 사용하세요.
다음 단계
- Python 시작하기 – Python에서 PDF Oxide 사용하기
- Rust 시작하기 – Rust에서 PDF Oxide 사용하기
- JavaScript API 레퍼런스 – WASM API 전체 문서
- 텍스트 추출 – 추출 옵션 상세
- PDF 생성 – 고급 생성 방법