Geração de relatórios PDF em Rust com a biblioteca printpdf
No desenvolvimento web moderno, a criação de documentos PDF continua sendo uma tarefa essencial — desde a geração de faturas e relatórios até a exportação de dados. Se o seu projeto é escrito em Rust ou você o utiliza para o backend, a biblioteca printpdf será uma ferramenta confiável para gerar PDFs. Neste artigo, exploraremos os recursos do printpdf, mostraremos exemplos de código e discutiremos como integrá-lo em um projeto educacional.
O que é printpdf?
printpdf é uma biblioteca Rust pura para criar documentos PDF sem dependências externas. Ela permite:
- Criar documentos de várias páginas com conteúdo arbitrário
- Adicionar texto com diferentes fontes (incluindo TrueType e OpenType)
- Desenhar linhas, retângulos, elipses e caminhos complexos
- Incorporar imagens (JPEG, PNG)
- Trabalhar com tabelas e grades
- Gerenciar espaços de cor (RGB, CMYK, Grayscale)
A principal vantagem é a total autonomia: não é necessário instalar LaTeX, wkhtmltopdf ou outros sistemas. Isso torna o printpdf a escolha ideal para o site educacional pythonlib.ru, onde a simplicidade de implantação e a reprodutibilidade dos exemplos são importantes.
Instalação e primeiro documento
Adicione a dependência no Cargo.toml:
[dependencies]printpdf = "0.7"Vamos criar um PDF simples com texto:
use printpdf::*;use std::fs::File;use std::io::BufWriter;
fn main() { // Criando um documento no formato A4 let (doc, page1, layer1) = PdfDocument::new( "Meu primeiro PDF", Mm(210.0), Mm(297.0), "Layer 1" );
// Obtendo a fonte padrão let font = doc.add_builtin_font(BuiltinFont::Helvetica).unwrap();
// Adicionando texto let current_layer = doc.get_page(page1).get_layer(layer1); current_layer.use_text( "Olá, PythonLib!", 24.0, Mm(10.0), Mm(280.0), &font );
// Salvando o arquivo let file = File::create("hello.pdf").unwrap(); let writer = BufWriter::new(file); doc.save(&mut writer).unwrap();
println!("PDF criado: hello.pdf");}Este código cria um PDF de uma página com um texto. Observe que use_text aceita coordenadas em milímetros e o tamanho da fonte em pontos.
Trabalhando com gráficos e cores
O printpdf suporta desenho de primitivas. Vamos criar um relatório com uma linha e um retângulo preenchido:
use printpdf::*;
fn create_report() -> (PdfDocumentReference, PdfPageIndex, PdfLayerIndex) { let (doc, page, layer) = PdfDocument::new( "Relatório", Mm(210.0), Mm(297.0), "Data" );
let layer = doc.get_page(page).get_layer(layer);
// Desenhando uma linha vermelha let points = vec![ (Point::new(Mm(20.0), Mm(250.0)), false), (Point::new(Mm(190.0), Mm(250.0)), false), ]; let line = Line { points, is_closed: false, }; layer.set_color(Color::Rgb(Rgb::new(1.0, 0.0, 0.0))); layer.add_line(line);
// Retângulo azul preenchido let rect = Polygon { vertices: vec![ (Point::new(Mm(50.0), Mm(200.0)), false), (Point::new(Mm(150.0), Mm(200.0)), false), (Point::new(Mm(150.0), Mm(180.0)), false), (Point::new(Mm(50.0), Mm(180.0)), false), ], is_closed: true, }; layer.set_color(Color::Rgb(Rgb::new(0.0, 0.0, 1.0))); layer.add_polygon(rect);
(doc, page, layer)}As cores são definidas no intervalo 0.0–1.0. Para CMYK, use Color::Cmyk(Cmyk::new(0.0, 1.0, 0.0, 0.0)).
Incorporação de imagens
Vamos adicionar um logotipo ao relatório:
use printpdf::*;use std::fs::Fi