Найкращий Rust-crate для PDF у 2026
PDF Oxide проти найпопулярніших Rust-crate для PDF: 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 файлів). Дивіться повні деталі корпусу.
| Бібліотека | Середнє | p99 | Рівень успіху | Вилучення тексту | Примітки |
|---|---|---|---|---|---|
| PDF Oxide | 0.8мс | 9мс | 100% | Вбудоване, виробничого рівня | Unicode, CJK, порядок читання |
| oxidize_pdf | 13.5мс | 11мс | 99.1% | Базове | Максимальний викид 48с |
| unpdf | 2.8мс | 10мс | 95.1% | Базове | 185 збоїв на повному корпусі |
| pdf_extract | 4.08мс | 37мс | 91.5% | Базове | Не справляється зі складними макетами |
| lopdf | 0.3мс | 2мс | 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% надійність з вилученням тексту виробничого рівня.
Порівняння дизайну 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. Вона надає типізований 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 | Так | Виробничого рівня (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 | Так | API високого рівня (Markdown/HTML) та низького рівня |
| 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 безпосередньо. Добре підходить для об’єднання, розділення та пакетної обробки PDF.
Оберіть printpdf, якщо ви лише створюєте PDF та ніколи не потребуєте їх читати. Найчистіший API для генерації звітів та документів.
Оберіть pdf-rs, якщо вам потрібен парсер, сумісний зі специфікацією, для аналізу PDF або ви будуєте власний конвеєр рендерингу.
Оберіть pdf_extract, якщо вам потрібне базове вилучення тексту і ви не потребуєте високої надійності або підтримки складних макетів.
Пов’язані сторінки
- Бенчмарки продуктивності – повні результати бенчмарків корпусу
- Початок роботи з Rust – встановлення та перше вилучення
- Довідник API Rust – повний API Rust
- Порівняння з бібліотеками PDF для Python – порівняння екосистеми Python