Geração de relatórios PDF em Rust: biblioteca printpdf

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

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,

Recommendations