Skip to content

Лучший Rust-крейт для PDF в 2026

PDF Oxide против самых популярных Rust-крейтов для PDF: lopdf, printpdf, pdf-rs и pdf_extract. Каждый крейт работает на своём уровне абстракции и закрывает разные задачи — эта страница поможет выбрать правильный для вашего проекта.

Обзор

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 файлов). См. подробное описание корпуса.

Библиотека Среднее p99 Успешность Извлечение текста Примечания
PDF Oxide 0.8ms 9ms 100% Встроенное, production-уровня 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% Нет встроенного извлечения Не справляется с 20% PDF

lopdf быстрее на тех PDF, которые может распарсить, — но он не справляется с 20% корпуса и не предоставляет извлечения текста. Вам придётся самостоятельно реализовать декодирование шрифтов, разрешение CMap и анализ пробелов.

pdf_extract предоставляет базовое извлечение текста, но имеет успешность 91.5% и плохо справляется со сложными макетами, текстом CJK и тегированными PDF. oxidize_pdf показывает приемлемую надёжность (99.1%), но работает в 17 раз медленнее pdf_oxide по среднему времени извлечения и имеет выброс в 48 секунд в худшем случае. unpdf обрабатывает весь корпус, но не справляется со 185 PDF.

PDF Oxide — единственный Rust-крейт, сочетающий 100% надёжность с извлечением текста production-уровня.

Сравнение дизайна API

PDF Oxide: высокоуровневый, ориентированный на задачи

PDF Oxide предоставляет готовые методы для типичных задач. Вы работаете с текстом, изображениями и полями форм, а не с PDF-объектами и словарями.

use pdf_oxide::PdfDocument;

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

// Извлечение текста — один вызов
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 для построения PDF-документов с нуля с текстом, изображениями и векторной графикой.

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 Да Production-уровня (Unicode, CJK, порядок чтения) Один вызов метода
pdf_extract Да Базовое (пропускает сложные макеты) Один вызов метода
lopdf Нет Н/Д Сотни строк пользовательского кода
printpdf Нет Н/Д Невозможно (только запись)
pdf-rs Нет Н/Д Значительный объём пользовательского кода

PDF Oxide обрабатывает декодирование CMap/ToUnicode, пробелы на основе метрик шрифтов, порядок чтения из дерева структуры и реконструкцию лигатур. Реализация аналогичной функциональности поверх lopdf или pdf-rs потребует тысяч строк кода и глубокого знания спецификации PDF.

Создание PDF

Библиотека Подход Ввод Markdown/HTML Таблицы Штрихкоды
PDF Oxide Высокоуровневый + низкоуровневый Да Да Да
lopdf Конструирование сырых объектов Нет Нет Нет
printpdf Типизированный API слоёв Нет Нет Нет
pdf-rs Н/Д (только чтение) Н/Д Н/Д Н/Д

Шифрование

Библиотека Чтение зашифрованных Запись зашифрованных Алгоритмы
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 МБ
lopdf ~15 ~10 с ~1 МБ
printpdf ~20 ~15 с ~2 МБ
pdf-rs ~25 ~20 с ~2 МБ

У 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 Да Единственный крейт, покрывающий все три задачи
lopdf + printpdf Частично Два крейта, нет извлечения текста
pdf-rs + printpdf Частично Два крейта, нет редактирования

Когда использовать какую библиотеку

Выбирайте PDF Oxide, если вам нужно больше одной PDF-возможности (извлечение + создание или извлечение + редактирование) и вы хотите единственную, хорошо протестированную зависимость с 100% надёжностью.

Выбирайте lopdf, если вам нужна низкоуровневая манипуляция структурой PDF и вы готовы работать со спецификацией напрямую. Хорош для объединения, разделения и пакетной обработки PDF.

Выбирайте printpdf, если вы только создаёте PDF и никогда не читаете их. Самый чистый API для генерации отчётов и документов.

Выбирайте pdf-rs, если вам нужен парсер, соответствующий спецификации, для анализа PDF или построения собственного рендеринг-пайплайна.

Выбирайте pdf_extract, если вам нужно базовое извлечение текста без требований к высокой надёжности или поддержке сложных макетов.

Связанные страницы