Generación de informes PDF en Rust: biblioteca printpdf

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Generación de informes PDF en Rust con la biblioteca printpdf



En el mundo de la programación moderna, Rust se utiliza cada vez más para crear aplicaciones de servidor de alto rendimiento y herramientas de línea de comandos. Una de las tareas más demandadas es la generación de informes PDF, ya sean paneles analíticos, facturas o documentación. La biblioteca printpdf proporciona una forma ligera y confiable de crear documentos PDF en Rust puro sin dependencias de sistemas externos (por ejemplo, LaTeX o wkhtmltopdf).



¿Qué es printpdf?



printpdf es una biblioteca pure-Rust para generar documentos PDF desde cero. Soporta:

  • Texto con varias fuentes (incluyendo TrueType/OpenType incrustadas).
  • Gráficos vectoriales (líneas, rectángulos, elipses).
  • Imágenes (PNG, JPEG) con transparencia.
  • Tablas y formato complejo mediante posicionamiento manual.
  • Páginas de cualquier tamaño (A4, Carta, personalizadas).


La biblioteca no utiliza procesos externos, lo que la hace ideal para integrarse en servicios web, utilidades CLI o aplicaciones de escritorio en Rust.



Instalación



Añada a Cargo.toml:



[dependencies]printpdf = "0.7"


También necesitará el crate rusttype para trabajar con fuentes (se incluye automáticamente como dependencia).



Ejemplo básico: creación de un informe simple



Escribamos un programa que cree un PDF con un título, texto y una línea. Guardaremos el resultado en el archivo report.pdf.



use printpdf::*;use std::fs::File;use std::io::BufWriter;

fn main() { // Creamos un documento en formato A4 let (doc, page1, layer1) = PdfDocument::new( "Mi informe", Mm(210.0), Mm(297.0), "Layer 1", );

// Obtenemos la fuente (Helvetica incorporada) let font = doc.add_builtin_font(BuiltinFont::Helvetica).unwrap();

// Empezamos a dibujar en la primera capa let current_layer = doc.get_page(page1).get_layer(layer1);

// Texto: título current_layer.use_text( "Informe de ventas", 24.0, Mm(20.0), Mm(270.0), &font, );

// Texto: normal current_layer.use_text( "Fecha del informe: 2025-03-15", 12.0, Mm(20.0), Mm(250.0), &font, );

// Dibujamos una línea 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)), );

// Guardamos en un archivo let file = File::create("report.pdf").unwrap(); let writer = BufWriter::new(file); doc.save(&mut std::io::BufWriter::new(writer)).unwrap();

println!("Informe PDF creado: report.pdf");}


Este código crea un PDF de una página con un título, una fecha y una línea gris. Todas las coordenadas se especifican en milímetros (también se pueden usar puntos).



Añadir una tabla con datos



Para los informes a menudo se necesitan tablas. En printpdf no hay estructuras de tabla predefinidas, pero se pueden implementar fácilmente 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);

// Fondo para el encabezado if row_idx == 0 { layer.set_fill_color(header_bg); layer.add_rectangle( start_x, y - row_height,

Recommendations