Generating PDF Reports in Rust: printpdf Library

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Generating PDF Reports in Rust with the printpdf Library



In modern web development, creating PDF documents remains a popular task — from generating invoices and reports to exporting data. If your project is written in Rust or you use it for the backend, the printpdf library will be a reliable tool for PDF generation. In this article, we will explore the capabilities of printpdf, show code examples, and discuss how to integrate it into an educational project.



What is printpdf?



printpdf is a pure Rust library for creating PDF documents without external dependencies. It allows you to:

  • Create multi-page documents with arbitrary content
  • Add text with various fonts (including TrueType and OpenType)
  • Draw lines, rectangles, ellipses, and complex paths
  • Embed images (JPEG, PNG)
  • Work with tables and grids
  • Manage color spaces (RGB, CMYK, Grayscale)


The main advantage is complete autonomy: no need to install LaTeX, wkhtmltopdf, or other systems. This makes printpdf an ideal choice for the educational website pythonlib.ru, where simplicity of deployment and reproducibility of examples are important.



Installation and First Document



Add the dependency to Cargo.toml:



[dependencies]printpdf = "0.7"


Let's create a simple PDF with text:



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

fn main() { // Create an A4 document let (doc, page1, layer1) = PdfDocument::new( "My First PDF", Mm(210.0), Mm(297.0), "Layer 1" );

// Get the default font let font = doc.add_builtin_font(BuiltinFont::Helvetica).unwrap();

// Add text let current_layer = doc.get_page(page1).get_layer(layer1); current_layer.use_text( "Hello, PythonLib!", 24.0, Mm(10.0), Mm(280.0), &font );

// Save the file let file = File::create("hello.pdf").unwrap(); let writer = BufWriter::new(file); doc.save(&mut writer).unwrap();

println!("PDF created: hello.pdf");}


This code creates a single-page PDF with a label. Note: use_text accepts coordinates in millimeters, and the font size in points.



Working with Graphics and Color



printpdf supports drawing primitives. Let's create a report with a line and a filled rectangle:



use printpdf::*;

fn create_report() -> (PdfDocumentReference, PdfPageIndex, PdfLayerIndex) { let (doc, page, layer) = PdfDocument::new( "Report", Mm(210.0), Mm(297.0), "Data" );

let layer = doc.get_page(page).get_layer(layer);

// Draw a red line 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);

// Filled blue rectangle 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)}


Colors are specified in the range 0.0–1.0. For CMYK, use Color::Cmyk(Cmyk::new(0.0, 1.0, 0.0, 0.0)).



Embedding Images



Let's add a logo to the report:



use printpdf::*;use std::fs::Fi                    

Recommendations