Skip to content

2026 年おすすめ Rust PDF crate 比較

PDF Oxide を主要な Rust PDF crate(lopdf、printpdf、pdf-rs、pdf_extract)と直接比較します。それぞれ抽象化レベルも想定ユースケースも異なるため、このページでは用途に合った crate 選びをサポートします。

概要

PDF Oxide lopdf printpdf pdf-rs pdf_extract
API レベル 高レベル 低レベル 中レベル(作成) 低レベル(読み取り) 中レベル(読み取り)
PDF 読み取り あり あり なし あり あり
PDF 書き込み あり あり あり なし なし
テキスト抽出 あり(高レベル) 手動 なし 手動 あり(基本的)
画像抽出 あり(高レベル) 手動 なし 手動 なし
フォームフィールド 読み書き 手動 なし 読み取りのみ なし
PDF 作成 あり あり あり なし なし
Markdown/HTML 入力 あり なし なし なし なし
既存 PDF の編集 あり あり(低レベル) なし なし なし
注釈 読み書き 手動 なし 読み取りのみ なし
暗号化 読み書き なし なし なし なし
PDF/A バリデーション あり なし なし なし なし
レンダリング あり(tiny-skia) なし なし 部分的 なし
Python バインディング あり なし なし なし なし
ライセンス MIT MIT MIT MIT Apache-2.0

すべてのライブラリがパーミッシブライセンスです。違いは機能範囲と抽象化レベルにあります。

パフォーマンス比較

コーパス全体ベンチマーク(3,830 PDF)

3,830 件の PDF コーパス全体でテスト。PDF 仕様準拠(veraPDF, 2,907 ファイル)、実際のブラウザレンダリングエッジケース(Mozilla pdf.js, 897 ファイル)、不正構造やファジング破損を含むセキュリティ/堅牢性ストレステスト(DARPA SafeDocs, 26 ファイル)の 3 つの独立した公開テストスイートで構成。詳細はコーパスの詳細をご覧ください。

ライブラリ 平均 p99 パス率 テキスト抽出 備考
PDF Oxide 0.8ms 9ms 100% 内蔵、プロダクショングレード Unicode, CJK, 読み取り順序
oxidize_pdf 13.5ms 11ms 99.1% 基本的 最大 48 秒の外れ値
unpdf 2.8ms 10ms 95.1% 基本的 コーパス全体で 185 件の失敗
pdf_extract 4.08ms 37ms 91.5% 基本的 複雑なレイアウトの欠落
lopdf 0.3ms 2ms 80.2% 内蔵抽出なし PDF の 20% でパース失敗

lopdf はパース可能な PDF では高速ですが、コーパスの 20% でパースに失敗し、テキスト抽出機能を提供していません。フォントデコード、CMap 解決、スペーシング分析を自分で構築する必要があります。

pdf_extract は基本的なテキスト抽出を提供しますが、パス率は 91.5% で、複雑なレイアウト、CJK テキスト、タグ付き PDF では苦戦します。oxidize_pdf は信頼性が良好(99.1%)ですが、平均抽出時間が pdf_oxide の 17 倍遅く、最悪ケースで 48 秒の外れ値があります。unpdf はコーパス全体を処理しますが、185 件の PDF で失敗します。

PDF Oxide は 100% の信頼性とプロダクショングレードのテキスト抽出を兼ね備えた唯一の Rust クレートです。

API 設計の比較

PDF Oxide: 高レベル、タスク指向

PDF Oxide は一般的なタスク向けの専用メソッドを提供します。PDF オブジェクトやディクショナリではなく、テキスト、画像、フォームフィールドを扱います。

use pdf_oxide::PdfDocument;

let mut doc = PdfDocument::open("report.pdf")?;

// テキスト抽出 -- 1 回の呼び出し
let text = doc.extract_text(0)?;
println!("{}", text);

// フォントメタデータ付きスタイルスパン
let spans = doc.extract_spans(0)?;
for span in &spans {
    println!("'{}' font={} size={:.1}pt", span.text, span.font_name, span.font_size);
}

// 画像抽出
let images = doc.extract_images(0)?;
for img in &images {
    println!("{}x{} {:?}", img.width, img.height, img.format);
}

// フォームフィールド
let fields = doc.extract_form_fields()?;
for field in &fields {
    println!("{}: {:?}", field.name, field.value);
}

PDF 作成も同様に直感的です:

use pdf_oxide::api::Pdf;

// Markdown から
let pdf = Pdf::from_markdown("# Report\n\n| A | B |\n|---|---|\n| 1 | 2 |")?;
pdf.save("report.pdf")?;

// HTML から
let pdf = Pdf::from_html("<h1>Report</h1><p>Content here.</p>")?;
pdf.save("report.pdf")?;

lopdf: 低レベルオブジェクト操作

lopdf は PDF オブジェクト、ストリーム、クロスリファレンステーブルへの直接アクセスを提供します。効果的に使用するには PDF 仕様の理解が必要です。テキスト抽出は内蔵されておらず、ディクショナリのナビゲーションとストリームのデコードを自分で行います。

use lopdf::Document;

let doc = Document::load("report.pdf")?;

// ページディクショナリの取得
let page_id = doc.page_iter().next().unwrap();
let page = doc.get_dictionary(page_id)?;

// コンテントストリームの取得 -- 手動作業
let contents = page.get("Contents")?;
let stream = doc.get_object(contents.as_reference()?)?;

// テキストを抽出するには:
// 1. コンテントストリーム演算子のパース
// 2. /Resources からのフォント参照の解決
// 3. CMap/ToUnicode マッピングのデコード
// 4. テキスト行列変換の適用
// 5. エンコーディングの違いへの対処
//
// lopdf はこれらを一切提供しません -- 生のオブジェクトアクセスのみ
println!("Page has {} objects", doc.objects.len());

lopdf は PDF 構造を直接操作する必要がある場合に適切なツールです: ドキュメントの結合、オブジェクトストリームの書き換え、特殊な PDF プロセッサの構築など。

printpdf: PDF 作成専用

printpdf は作成専用のライブラリです。既存の PDF の読み取りやパースはできません。テキスト、画像、ベクターグラフィックスで PDF ドキュメントをゼロから構築するための型付き API を提供します。

use printpdf::*;

let (doc, page1, layer1) = PdfDocument::new(
    "Report", Mm(210.0), Mm(297.0), "Layer 1"
);

let current_layer = doc.get_page(page1).get_layer(layer1);

// テキスト追加 -- 手動フォント読み込みが必要
let font = doc.add_builtin_font(BuiltinFont::Helvetica)?;
current_layer.use_text("Hello World", 24.0, Mm(10.0), Mm(280.0), &font);

// 保存
doc.save(&mut std::io::BufWriter::new(
    std::fs::File::create("output.pdf")?,
))?;

// 既存 PDF の読み取りは不可
// テキスト、画像、フォームフィールドの抽出は不可

printpdf は新しい PDF の生成のみが必要で、クリーンで集中した作成 API が欲しい場合に適切なツールです。

pdf-rs: 低レベル PDF 読み取り

pdf-rs は PDF 構造を Rust の型にパースしますが、高レベル機能は最小限です。PDF オブジェクトへの型付きアクセスは得られますが、テキストデコード、フォント解決、コンテントストリームパースは自分で処理する必要があります。

use pdf::file::FileOptions;

let file = FileOptions::cached().open("report.pdf")?;

// ページオブジェクトへのアクセス
let page = file.get_page(0)?;
let media_box = page.media_box()?;
println!("Page size: {:?}", media_box);

// コンテントストリームアクセス -- 低レベル
if let Some(ref contents) = page.contents {
    // 生の演算子を返す -- 自分で解釈が必要
    // テキスト組み立て、フォントデコード、レイアウト分析は内蔵なし
}

// PDF の書き込みや変更は不可

pdf-rs は分析、バリデーション、カスタムレンダラーの構築のために型安全な PDF パーサーが必要な場合に適切なツールです。

タスク別機能比較

テキスト抽出

ライブラリ 内蔵 品質 必要な工数
PDF Oxide あり プロダクショングレード(Unicode, CJK, 読み取り順序) メソッド 1 回の呼び出し
pdf_extract あり 基本的(複雑なレイアウトの欠落) メソッド 1 回の呼び出し
lopdf なし N/A 数百行のカスタムコード
printpdf なし N/A 不可(書き込み専用)
pdf-rs なし N/A 大量のカスタムコードが必要

PDF Oxide は CMap/ToUnicode デコード、フォントメトリクスベースのスペーシング、構造ツリーの読み取り順序、リガチャ再構成を処理します。lopdf や pdf-rs の上に同等の機能を実装するには数千行のコードと PDF 仕様の深い知識が必要です。

PDF 作成

ライブラリ アプローチ Markdown/HTML 入力 テーブル バーコード
PDF Oxide 高レベル + 低レベル あり あり あり
lopdf 生オブジェクト構築 なし なし なし
printpdf 型付きレイヤー API なし なし なし
pdf-rs N/A(読み取り専用) N/A N/A N/A

暗号化

ライブラリ 暗号化読み取り 暗号化書き込み アルゴリズム
PDF Oxide あり あり RC4-40, RC4-128, AES-128, AES-256
lopdf なし なし
printpdf なし なし
pdf-rs 部分的 なし RC4 のみ

準拠バリデーション

ライブラリ PDF/A PDF/X PDF/UA
PDF Oxide バリデーション + 変換 バリデーション バリデーション
lopdf なし なし なし
printpdf 部分的(PDF/A-1b 出力) なし なし
pdf-rs なし なし なし

依存関係のフットプリント

ライブラリ 依存数 コンパイル時間 バイナリサイズ
PDF Oxide ~40(コア) ~30 秒 ~4 MB
lopdf ~15 ~10 秒 ~1 MB
printpdf ~20 ~15 秒 ~2 MB
pdf-rs ~25 ~20 秒 ~2 MB

PDF Oxide の依存数が多いのは、他のライブラリがユーザーに任せるか完全に省略しているフォントパース、画像デコード、コンテントストリーム解釈、暗号化などの機能を含んでいるためです。すべてのオプション機能(rendering, barcodes, office)を有効にすると ~100 に増加します。

ライブラリの組み合わせ

すべてパーミッシブライセンスのため、同一プロジェクトで組み合わせることができます:

[dependencies]
pdf_oxide = "0.3"
lopdf = "0.32"        # オプション: エッジケース用の生オブジェクトアクセス

一般的なパターン:

  • PDF Oxide + lopdf: 抽出と作成に PDF Oxide、生オブジェクト操作が必要なエッジケースに lopdf をフォールバック。
  • PDF Oxide + printpdf: 読み取りに PDF Oxide、特殊な作成ワークフローに printpdf。

ユースケース一覧

「PDF からテキストを抽出したい」

クレート 適切? 備考
PDF Oxide はい 最高品質の抽出、100% パス率、読み取り順序、フォントメタデータ
pdf_extract 部分的 基本的な抽出、91.5% パス率
lopdf いいえ テキスト抽出なし
printpdf いいえ PDF の読み取り不可
pdf-rs 部分的 基本的なパース、高レベルテキスト抽出なし

「PDF を作成したい」

クレート 適切? 備考
PDF Oxide はい 高レベル(Markdown/HTML)と低レベル API
lopdf 部分的 低レベルオブジェクト構築
printpdf はい クリーンな作成 API、読み取り不可
pdf-rs いいえ 読み取り専用

「既存の PDF を編集したい」

クレート 適切? 備考
PDF Oxide はい DOM ライクな編集、注釈、フォーム
lopdf 部分的 低レベルオブジェクト操作
printpdf いいえ PDF の読み取り不可
pdf-rs いいえ 読み取り専用

「フルライフサイクル(抽出 + 作成 + 編集)が必要」

クレート 適切? 備考
PDF Oxide はい 3 つすべてをカバーする唯一のクレート
lopdf + printpdf 部分的 2 クレート、テキスト抽出なし
pdf-rs + printpdf 部分的 2 クレート、編集なし

使い分けガイド

PDF Oxide を選ぶ場合: 複数の PDF 機能(抽出 + 作成、または抽出 + 編集)が必要で、100% の信頼性を持つ十分にテストされた単一の依存パッケージが欲しい場合。

lopdf を選ぶ場合: 低レベルの PDF 構造操作が必要で、PDF 仕様を直接扱うことに慣れている場合。結合、分割、バッチ PDF 処理に適しています。

printpdf を選ぶ場合: PDF の作成のみで読み取りが不要な場合。レポートやドキュメント生成に最もクリーンな API。

pdf-rs を選ぶ場合: PDF 分析用の仕様準拠パーサーが必要、またはカスタムレンダリングパイプラインを構築している場合。

pdf_extract を選ぶ場合: 基本的なテキスト抽出が必要で、高い信頼性や複雑なレイアウトサポートは不要な場合。

関連ページ