Geração de relatórios PDF em Rust com a biblioteca printpdf
No mundo moderno da programação, Rust é cada vez mais usado para criar aplicações servidoras de alto desempenho e ferramentas de linha de comando. Uma das tarefas mais requisitadas é a geração de relatórios PDF — sejam painéis analíticos, faturas ou documentação. A biblioteca printpdf fornece uma maneira leve e confiável de criar documentos PDF em Rust puro, sem dependências de sistemas externos (como LaTeX ou wkhtmltopdf).
O que é printpdf?
printpdf é uma biblioteca pure-Rust para gerar documentos PDF do zero. Ela suporta:
- Texto com várias fontes (incluindo TrueType/OpenType incorporadas).
- Gráficos vetoriais (linhas, retângulos, elipses).
- Imagens (PNG, JPEG) com transparência.
- Tabelas e formatação complexa através de posicionamento manual.
- Páginas de qualquer tamanho (A4, Carta, personalizadas).
A biblioteca não usa processos externos, tornando-a ideal para incorporação em serviços web, utilitários CLI ou aplicações desktop em Rust.
Instalação
Adicione ao Cargo.toml:
[dependencies]printpdf = "0.7"Você também precisará do crate rusttype para trabalhar com fontes (ele é puxado automaticamente como dependência).
Exemplo básico: criando um relatório simples
Vamos escrever um programa que cria um PDF com título, texto e uma linha. O resultado será salvo no arquivo report.pdf.
use printpdf::*;use std::fs::File;use std::io::BufWriter;
fn main() { // Criando um documento formato A4 let (doc, page1, layer1) = PdfDocument::new( "Meu relatório", Mm(210.0), Mm(297.0), "Layer 1", );
// Obtendo a fonte (Helvetica embutida) let font = doc.add_builtin_font(BuiltinFont::Helvetica).unwrap();
// Começando a desenhar na primeira camada let current_layer = doc.get_page(page1).get_layer(layer1);
// Texto: título current_layer.use_text( "Relatório de vendas", 24.0, Mm(20.0), Mm(270.0), &font, );
// Texto: normal current_layer.use_text( "Data do relatório: 2025-03-15", 12.0, Mm(20.0), Mm(250.0), &font, );
// Desenhando uma linha separadora current_layer.set_outline_color(Color::Rgb(Rgb::new(0.5, 0.5, 0.5))); current_layer.set_stroke_width(1.0); current_layer.add_line( Point::new(Mm(20.0), Mm(240.0)), Point::new(Mm(190.0), Mm(240.0)), );
// Salvando no arquivo let file = File::create("report.pdf").unwrap(); let writer = BufWriter::new(file); doc.save(&mut std::io::BufWriter::new(writer)).unwrap();
println!("Relatório PDF criado: report.pdf");}Este código cria um PDF de uma página com título, data e uma linha cinza. Todas as coordenadas são definidas em milímetros (também é possível usar pontos).
Adicionando uma tabela com dados
Para relatórios, tabelas são frequentemente necessárias. No printpdf não há estruturas de tabela prontas, mas elas podem ser facilmente implementadas manualmente:
use printpdf::*;use std::fs::File;use std::io::BufWriter;
fn draw_table( layer: &PdfLayerReference, font: &IndirectFontRef, data: Vec<[&str; 3]>, start_x: Mm, start_y: Mm,) { let col_widths = [Mm(40.0), Mm(60.0), Mm(50.0)]; let row_height = Mm(10.0); let header_bg = Color::Rgb(Rgb::new(0.9, 0.9, 0.9));
for (row_idx, row_data) in data.iter().enumerate() { let y = start_y - row_height * (row_idx as f32);
// Fundo para o cabeçalho if row_idx == 0 { layer.set_fill_color(header_bg); layer.add_rectangle( start_x, y - row_height, Também na biblioteca
Agendador de Tarefas Swift: GCD, OperationQueue e Timer no iOS/macOS
Geração de PDF em TypeScript: bibliotecas e ferramentas para Node.js
Testes em Swift (iOS/macOS): frameworks e ferramentas
Trabalhando com Markdown em Kotlin: bibliotecas, parsing e geração