PDF Generation in Rust: Overview of Libraries and Tools
The Rust language, known for its performance and safety, offers several powerful libraries for creating PDF documents. Unlike Python, where reportlab and fpdf dominate, the Rust ecosystem provides lightweight yet functional solutions. In this article, we will look at three key libraries: printpdf, genpdf, and pdf-writer, and also touch upon low-level approaches.
1. printpdf — Basic but Flexible Library
printpdf is one of the most popular libraries for PDF generation in Rust. It provides low-level access to the PDF structure, allowing you to create documents with arbitrary element positioning. The library supports font embedding, working with images, and basic graphics primitives.
Usage Example:
use printpdf::*;use std::fs::File;use std::io::BufWriter;
fn main() { let (doc, page1, layer1) = PdfDocument::new("PDF Document", Mm(210.0), Mm(297.0), "Layer 1");
let font = doc.add_builtin_font(BuiltinFont::Helvetica).unwrap();
// Add text doc.use_text("Hello, world!", 24.0, Mm(20.0), Mm(280.0), &font);
// Draw a line let layer = doc.get_page(page1).get_layer(layer1); layer.set_color(Color::Rgb(Rgb::new(0.0, 0.0, 0.0), None)); layer.add_line(Point::new(Mm(20.0), Mm(270.0)), Point::new(Mm(100.0), Mm(270.0)));
// Save let file = File::create("example.pdf").unwrap(); doc.save(&mut BufWriter::new(file)).unwrap();}Pros:
- Full control over the PDF structure
- Support for embedding TrueType fonts
- Working with images (PNG, JPEG)
- Support for SVG graphics (via
printpdf-svg)
Cons:
- No automatic text layout
- Need to manually manage positioning
- Lack of support for tables and multi-page layouts
2. genpdf — For Simple Documents with Layout
genpdf is a higher-level library that automates the layout process. It is ideal for creating reports, letters, and other documents with a simple structure. The library supports line wrapping, text alignment, and basic design elements.
Example of Creating a Simple Document:
use genpdf::{Document, SimplePageSettings};use genpdf::elements::{Paragraph, Break, Image};use genpdf::fonts::FontFamily;
fn main() -> Result<(), Box> { let font_family = FontFamily::from_files( "fonts/", "LiberationSans", None )?;
let mut doc = Document::new(font_family); doc.set_title("Example Document");
// Add elements doc.push(Paragraph::new("Title").bold()); doc.push(Break::new(5.0)); doc.push(Paragraph::new("Main text with automatic line wrapping. " .to_string() + "The genpdf library calculates positions on its own."));
// Save doc.render_to_file("output.pdf")?; Ok(())} Pros:
- Automatic text layout
- Support for wrapping and alignment
- Simple API for adding elements
- Ability to create multi-page documents
Cons:
- Limited graphics support
- No built-in table support
- Less control over positioning
3. pdf-writer — Low-Level Performance
pdf-writer is a minimalistic library for directly writing PDF objects. It