Melhor crate PDF para Rust em 2026
PDF Oxide frente aos crates PDF mais usados em Rust: lopdf, printpdf, pdf-rs e pdf_extract. Cada um mira um nível de abstração e casos de uso diferentes — esta página ajuda a escolher o crate certo para o seu projeto.
Resumo
| PDF Oxide | lopdf | printpdf | pdf-rs | pdf_extract | |
|---|---|---|---|---|---|
| Nível de API | Alto nível | Baixo nível | Médio nível (criação) | Baixo nível (leitura) | Médio nível (leitura) |
| Ler PDFs | Sim | Sim | Não | Sim | Sim |
| Escrever PDFs | Sim | Sim | Sim | Não | Não |
| Extração de texto | Sim (alto nível) | Manual | Não | Manual | Sim (básico) |
| Extração de imagens | Sim (alto nível) | Manual | Não | Manual | Não |
| Campos de formulário | Leitura + Escrita | Manual | Não | Somente leitura | Não |
| Criação de PDF | Sim | Sim | Sim | Não | Não |
| Entrada Markdown/HTML | Sim | Não | Não | Não | Não |
| Edição de PDFs existentes | Sim | Sim (baixo nível) | Não | Não | Não |
| Anotações | Leitura + Escrita | Manual | Não | Somente leitura | Não |
| Criptografia | Leitura + Escrita | Não | Não | Não | Não |
| Validação PDF/A | Sim | Não | Não | Não | Não |
| Renderização | Sim (tiny-skia) | Não | Não | Parcial | Não |
| Bindings Python | Sim | Não | Não | Não | Não |
| Licença | MIT | MIT | MIT | MIT | Apache-2.0 |
Todas as bibliotecas possuem licenças permissivas. As diferenças estão no escopo e no nível de abstração.
Comparação de Desempenho
Benchmark do Corpus Completo (3.830 PDFs)
Testado no corpus completo de 3.830 PDFs — três suítes de teste independentes e publicamente disponíveis cobrindo conformidade com a especificação PDF (veraPDF, 2.907 arquivos), casos extremos de renderização em navegadores do mundo real (Mozilla pdf.js, 897 arquivos) e testes de estresse de segurança/robustez incluindo estruturas malformadas e corrupção gerada por fuzzing (DARPA SafeDocs, 26 arquivos). Veja detalhes completos do corpus.
| Biblioteca | Média | p99 | Taxa de Aprovação | Extração de Texto | Observações |
|---|---|---|---|---|---|
| PDF Oxide | 0.8ms | 9ms | 100% | Integrada, nível de produção | Unicode, CJK, ordem de leitura |
| oxidize_pdf | 13.5ms | 11ms | 99.1% | Básica | Outlier máximo de 48s |
| unpdf | 2.8ms | 10ms | 95.1% | Básica | 185 falhas no corpus completo |
| pdf_extract | 4.08ms | 37ms | 91.5% | Básica | Falha em layouts complexos |
| lopdf | 0.3ms | 2ms | 80.2% | Sem extração integrada | Falha em 20% dos PDFs |
O lopdf é mais rápido nos PDFs que consegue analisar — mas falha em 20% do corpus e não fornece extração de texto. Você precisaria construir decodificação de fontes, resolução de CMap e análise de espaçamento por conta própria.
O pdf_extract fornece extração de texto básica mas tem uma taxa de aprovação de 91.5% e tem dificuldade com layouts complexos, texto CJK e PDFs com tags. O oxidize_pdf tem confiabilidade decente (99.1%) mas é 17× mais lento que o pdf_oxide no tempo médio de extração, com um outlier de pior caso de 48 segundos. O unpdf processa o corpus completo mas falha em 185 PDFs.
O PDF Oxide é o único crate Rust que combina 100% de confiabilidade com extração de texto em nível de produção.
Comparação de Design de API
PDF Oxide: Alto Nível, Orientado a Tarefas
O PDF Oxide fornece métodos dedicados para tarefas comuns. Você trabalha com texto, imagens e campos de formulário — não com objetos e dicionários PDF.
use pdf_oxide::PdfDocument;
let mut doc = PdfDocument::open("report.pdf")?;
// Extração de texto -- one call
let text = doc.extract_text(0)?;
println!("{}", text);
// Styled spans with font metadata
let spans = doc.extract_spans(0)?;
for span in &spans {
println!("'{}' font={} size={:.1}pt", span.text, span.font_name, span.font_size);
}
// Image extraction
let images = doc.extract_images(0)?;
for img in &images {
println!("{}x{} {:?}", img.width, img.height, img.format);
}
// Campos de formulário
let fields = doc.extract_form_fields()?;
for field in &fields {
println!("{}: {:?}", field.name, field.value);
}
A criação de PDFs é igualmente simples:
use pdf_oxide::api::Pdf;
// From Markdown
let pdf = Pdf::from_markdown("# Report\n\n| A | B |\n|---|---|\n| 1 | 2 |")?;
pdf.save("report.pdf")?;
// From HTML
let pdf = Pdf::from_html("<h1>Report</h1><p>Content here.</p>")?;
pdf.save("report.pdf")?;
lopdf: Manipulação de Objetos de Baixo Nível
O lopdf fornece acesso direto a objetos PDF, streams e tabela de referência cruzada. Você precisa entender a especificação PDF para usá-lo efetivamente. Não há extração de texto integrada — você navega pelos dicionários e decodifica os streams por conta própria.
use lopdf::Document;
let doc = Document::load("report.pdf")?;
// Get page dictionary
let page_id = doc.page_iter().next().unwrap();
let page = doc.get_dictionary(page_id)?;
// Get content stream -- manual work
let contents = page.get("Contents")?;
let stream = doc.get_object(contents.as_reference()?)?;
// To extract text you must:
// 1. Parse the content stream operators
// 2. Resolve font references from /Resources
// 3. Decode CMap/ToUnicode mappings
// 4. Apply text matrix transformations
// 5. Handle encoding differences
//
// lopdf does not provide any of this -- it is raw object access
println!("Page has {} objects", doc.objects.len());
O lopdf é a ferramenta certa quando você precisa manipular a estrutura do PDF diretamente: mesclar documentos, reescrever streams de objetos ou construir processadores de PDF especializados.
printpdf: Apenas Criação de PDF
O printpdf é uma biblioteca somente para criação. Não pode ler ou analisar PDFs existentes. Fornece uma API tipada para construir documentos PDF do zero com texto, imagens e gráficos vetoriais.
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);
// Add text -- requires manual font loading
let font = doc.add_builtin_font(BuiltinFont::Helvetica)?;
current_layer.use_text("Hello World", 24.0, Mm(10.0), Mm(280.0), &font);
// Save
doc.save(&mut std::io::BufWriter::new(
std::fs::File::create("output.pdf")?,
))?;
// Cannot read existing PDFs
// Cannot extract text, images, or form fields
O printpdf é a ferramenta certa quando você só precisa gerar novos PDFs e quer uma API de criação limpa e focada.
pdf-rs: Leitura de PDF de Baixo Nível
O pdf-rs analisa a estrutura do PDF em tipos Rust mas fornece funcionalidade de alto nível mínima. Você obtém acesso tipado a objetos PDF mas ainda precisa lidar com decodificação de texto, resolução de fontes e análise de content stream.
use pdf::file::FileOptions;
let file = FileOptions::cached().open("report.pdf")?;
// Access page objects
let page = file.get_page(0)?;
let media_box = page.media_box()?;
println!("Page size: {:?}", media_box);
// Content stream access -- low-level
if let Some(ref contents) = page.contents {
// Returns raw operations -- you must interpret them
// No built-in text assembly, font decoding, or layout analysis
}
// Cannot write or modify PDFs
O pdf-rs é a ferramenta certa quando você precisa de um parser PDF type-safe para análise, validação ou construção de um renderizador personalizado.
Comparação de Funcionalidades por Tarefa
Extração de Texto
| Biblioteca | Integrada | Qualidade | Esforço Necessário |
|---|---|---|---|
| PDF Oxide | Sim | Nível de produção (Unicode, CJK, ordem de leitura) | Uma chamada de método |
| pdf_extract | Sim | Básica (falha em layouts complexos) | Uma chamada de método |
| lopdf | Não | N/A | Centenas de linhas de código personalizado |
| printpdf | Não | N/A | Não é possível (somente escrita) |
| pdf-rs | Não | N/A | Código personalizado significativo necessário |
O PDF Oxide lida com decodificação CMap/ToUnicode, espaçamento baseado em métricas de fonte, ordem de leitura da árvore de estrutura e reconstrução de ligaturas. Implementar funcionalidade equivalente sobre o lopdf ou pdf-rs requer milhares de linhas de código e profundo conhecimento da especificação PDF.
Criação de PDF
| Biblioteca | Abordagem | Entrada Markdown/HTML | Tabelas | Códigos de Barras |
|---|---|---|---|---|
| PDF Oxide | Alto nível + baixo nível | Sim | Sim | Sim |
| lopdf | Construção de objetos bruta | Não | Não | Não |
| printpdf | API de camadas tipada | Não | Não | Não |
| pdf-rs | N/A (somente leitura) | N/A | N/A | N/A |
Criptografia
| Biblioteca | Leitura Criptografada | Escrita Criptografada | Algoritmos |
|---|---|---|---|
| PDF Oxide | Sim | Sim | RC4-40, RC4-128, AES-128, AES-256 |
| lopdf | Não | Não | – |
| printpdf | Não | Não | – |
| pdf-rs | Parcial | Não | Apenas RC4 |
Conformidade
| Biblioteca | PDF/A | PDF/X | PDF/UA |
|---|---|---|---|
| PDF Oxide | Validar + Converter | Validar | Validar |
| lopdf | Não | Não | Não |
| printpdf | Parcial (saída PDF/A-1b) | Não | Não |
| pdf-rs | Não | Não | Não |
Pegada de Dependências
| Biblioteca | Dependências | Tempo de Compilação | Tamanho do Binário |
|---|---|---|---|
| PDF Oxide | ~40 (core) | ~30s | ~4 MB |
| lopdf | ~15 | ~10s | ~1 MB |
| printpdf | ~20 | ~15s | ~2 MB |
| pdf-rs | ~25 | ~20s | ~2 MB |
O PDF Oxide possui mais dependências porque inclui análise de fontes, decodificação de imagens, interpretação de content stream e criptografia — funcionalidades que as outras bibliotecas deixam para o usuário ou omitem completamente. Com todas as features opcionais (rendering, barcodes, office), o número sobe para ~100.
Combinando Bibliotecas
Como todas possuem licenças permissivas, você pode combiná-las em um único projeto:
[dependencies]
pdf_oxide = "0.3"
lopdf = "0.32" # Optional: raw object access for edge cases
Padrões comuns:
- PDF Oxide + lopdf: Use PDF Oxide para extração e criação, com fallback para lopdf em casos extremos que requerem manipulação bruta de objetos.
- PDF Oxide + printpdf: Use PDF Oxide para leitura e printpdf para fluxos de trabalho de criação especializados.
Matriz de Casos de Uso
“Preciso extrair texto de PDFs”
| Crate | Adequado? | Observações |
|---|---|---|
| PDF Oxide | Sim | Melhor qualidade de extração, 100% de taxa de aprovação, ordem de leitura, metadados de fonte |
| pdf_extract | Parcial | Extração básica, 91.5% de taxa de aprovação |
| lopdf | Não | Sem extração de texto |
| printpdf | Não | Não pode ler PDFs |
| pdf-rs | Parcial | Análise básica, sem extração de texto de alto nível |
“Preciso criar PDFs”
| Crate | Adequado? | Observações |
|---|---|---|
| PDF Oxide | Sim | APIs de alto nível (Markdown/HTML) e baixo nível |
| lopdf | Parcial | Construção de objetos de baixo nível |
| printpdf | Sim | API de criação limpa, sem leitura |
| pdf-rs | Não | Somente leitura |
“Preciso editar PDFs existentes”
| Crate | Adequado? | Observações |
|---|---|---|
| PDF Oxide | Sim | Edição tipo DOM, anotações, formulários |
| lopdf | Parcial | Manipulação de objetos de baixo nível |
| printpdf | Não | Não pode ler PDFs |
| pdf-rs | Não | Somente leitura |
“Preciso do ciclo de vida completo (extrair + criar + editar)”
| Crate | Adequado? | Observações |
|---|---|---|
| PDF Oxide | Sim | Único crate que cobre os três |
| lopdf + printpdf | Parcial | Dois crates, sem extração de texto |
| pdf-rs + printpdf | Parcial | Dois crates, sem edição |
Quando Usar Cada Uma
Escolha PDF Oxide se você precisa de mais de uma capacidade PDF (extração + criação, ou extração + edição) e quer uma única dependência bem testada com 100% de confiabilidade.
Escolha lopdf se você precisa de manipulação de estrutura PDF de baixo nível e está confortável trabalhando diretamente com a especificação PDF. Bom para mesclagem, divisão e processamento em lote de PDFs.
Escolha printpdf se você só cria PDFs e nunca precisa lê-los. A API mais limpa para geração de relatórios e documentos.
Escolha pdf-rs se você precisa de um parser compatível com a especificação para análise de PDF ou está construindo seu próprio pipeline de renderização.
Escolha pdf_extract se você precisa de extração de texto básica e não requer alta confiabilidade ou suporte a layouts complexos.
Páginas Relacionadas
- Benchmarks de Desempenho – resultados completos de benchmark do corpus
- Primeiros Passos com Rust – instalação e primeira extração
- Referência da API Rust – API Rust completa
- vs Bibliotecas PDF para Python – comparação do ecossistema Python