PDF генерация на Rust: обзор библиотек и примеры кода

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

PDF генерация в Rust: обзор библиотек и практические примеры

Rust — язык системного программирования, который всё чаще используется для создания высокопроизводительных серверных приложений, веб-сервисов и инструментов командной строки. Одной из частых задач при разработке таких проектов является генерация PDF-документов: отчётов, счетов, сертификатов или просто текстовых файлов с форматированием. В этой статье мы рассмотрим основные библиотеки для работы с PDF на Rust, их возможности, примеры кода и критерии выбора.

Популярные библиотеки для генерации PDF на Rust

На текущий момент в экосистеме Rust можно выделить три основные библиотеки, которые активно поддерживаются и используются сообществом:

  • printpdf — низкоуровневая библиотека для создания PDF-документов с полным контролем над содержимым. Поддерживает текст, изображения, векторную графику, таблицы и встраивание шрифтов.
  • genpdf — библиотека более высокого уровня, построенная на основе printpdf. Предоставляет удобные абстракции для работы с текстом, параграфами, таблицами и стилями.
  • pdf_writer — ещё одна низкоуровневая библиотека, которая фокусируется на минимализме и производительности. Позволяет писать PDF-файлы напрямую, но требует глубокого понимания формата PDF.

Библиотека printpdf

printpdf — это одна из самых популярных библиотек для генерации PDF на Rust. Она предоставляет API для работы с графическими примитивами, текстом и шрифтами. Основные возможности:

  • Создание многостраничных документов;
  • Встраивание TrueType/OpenType шрифтов;
  • Рисование линий, прямоугольников, кругов и других фигур;
  • Вставка изображений (PNG, JPEG);
  • Работа с цветами и прозрачностью;
  • Поддержка Unicode и кириллицы.

Пример создания простого PDF с текстом с использованием printpdf:

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

fn main() {
    // Создаём документ формата A4
    let (doc, page1, layer1) = PdfDocument::new(
        "Пример PDF на Rust",
        Mm(210.0),
        Mm(297.0),
        "Layer 1",
    );

    // Получаем текущий шрифт (встроенный Helvetica)
    let font = doc.add_builtin_font(BuiltinFont::Helvetica).unwrap();

    // Используем слой для рисования
    let layer = doc.get_page(page1).get_layer(layer1);

    // Добавляем текст
    layer.use_text("Привет, мир! PDF из Rust", 24.0, Mm(50.0), Mm(250.0), &font);

    // Сохраняем файл
    let file = File::create("hello.pdf").unwrap();
    let writer = BufWriter::new(file);
    doc.save(&mut std::io::BufWriter::new(writer)).unwrap();
}

Библиотека genpdf

genpdf — это обёртка над printpdf, которая предоставляет более высокоуровневый API. Она идеально подходит для создания документов с простым форматированием: заголовки, параграфы, списки, таблицы. Основные преимущества:

  • Автоматическое управление разрывами страниц;
  • Поддержка стилей (жирный, курсив, подчёркивание);
  • Встроенная поддержка таблиц с ячейками и границами;
  • Простой интерфейс для добавления элементов.

Пример создания PDF с таблицей с использованием genpdf:

use genpdf::*;
use genpdf::elements::*;
use std::fs::File;

fn main() {
    // Создаём документ
    let mut doc = Document::new("Liberation Serif")
        .expect("Failed to load font");

    // Настройка стиля по умолчанию
    doc.set_title("Отчёт о продажах");

    // Добавляем параграф
    doc.push(Paragraph::new("Продажи по месяцам:"));

    // Создаём таблицу
    let mut table = Table::new(vec![2, 3, 2]);
    table.set_cell_border_style(BorderStyle::Solid);
    table.push_row(vec![
        "Месяц".to_string(),
        "Выручка, руб.".to_string(),
        "Кол-во".to_string(),
    ]);
    table.push_row(vec![
        "Январь".to_string(),
        "150000".to_string(),
        "120".to_string(),
    ]);
    table.push_row(vec![
        "Февраль".to_string(),
        "180000".to_string(),
        "145".to_string(),
    ]);

    doc.push(table);

    // Сохраняем
    let file = File::create("report.pdf").unwrap();
    doc.render(&mut std::io::BufWriter::new(file)).unwrap();
}

Библиотека pdf_writer

pdf_writer — это минимали

Рекомендаций