PDF Generation in Rust: Library Overview and Practical Examples
Rust is a systems programming language increasingly used for building high-performance server applications, web services, and command-line tools. One common task in developing such projects is generating PDF documents: reports, invoices, certificates, or simply formatted text files. In this article, we will review the main libraries for working with PDF in Rust, their capabilities, code examples, and selection criteria.
Popular Libraries for PDF Generation in Rust
Currently, in the Rust ecosystem, three main libraries stand out that are actively maintained and used by the community:
- printpdf — a low-level library for creating PDF documents with full control over content. Supports text, images, vector graphics, tables, and font embedding.
- genpdf — a higher-level library built on top of printpdf. Provides convenient abstractions for working with text, paragraphs, tables, and styles.
- pdf_writer — another low-level library that focuses on minimalism and performance. Allows writing PDF files directly but requires a deep understanding of the PDF format.
The printpdf Library
printpdf is one of the most popular libraries for PDF generation in Rust. It provides an API for working with graphic primitives, text, and fonts. Key features:
- Creating multi-page documents;
- Embedding TrueType/OpenType fonts;
- Drawing lines, rectangles, circles, and other shapes;
- Inserting images (PNG, JPEG);
- Working with colors and transparency;
- Support for Unicode and Cyrillic characters.
Example of creating a simple PDF with text using printpdf:
use printpdf::*;use std::fs::File;use std::io::BufWriter;
fn main() { // Create an A4 document let (doc, page1, layer1) = PdfDocument::new( "Example PDF in Rust", Mm(210.0), Mm(297.0), "Layer 1", );
// Get the current font (built-in Helvetica) let font = doc.add_builtin_font(BuiltinFont::Helvetica).unwrap();
// Use the layer for drawing let layer = doc.get_page(page1).get_layer(layer1);
// Add text layer.use_text("Hello, world! PDF from Rust", 24.0, Mm(50.0), Mm(250.0), &font);
// Save the file let file = File::create("hello.pdf").unwrap(); let writer = BufWriter::new(file); doc.save(&mut std::io::BufWriter::new(writer)).unwrap();}The genpdf Library
genpdf is a wrapper around printpdf that provides a higher-level API. It is ideal for creating documents with simple formatting: headings, paragraphs, lists, tables. Key advantages:
- Automatic page break management;
- Support for styles (bold, italic, underline);
- Built-in support for tables with cells and borders;
- Simple interface for adding elements.
Example of creating a PDF with a table using genpdf:
use genpdf::*;use genpdf::elements::*;use std::fs::File;
fn main() { // Create a document let mut doc = Document::new("Liberation Serif") .expect("Failed to load font");
// Configure default style doc.set_title("Sales Report");
// Add a paragraph doc.push(Paragraph::new("Sales by month:"));
// Create a table let mut table = Table::new(vec![2, 3, 2]); table.set_cell_border_style(BorderStyle::Solid); table.push_row(vec![ "Month".to_string(), "Revenue, RUB".to_stri Also in library
Redis client for C# (.NET): StackExchange.Redis — connection and examples
Internationalization (i18n) in PHP: A Complete Guide with Examples
TypeScript Standard Library: A Complete Overview for Developers