Skip to content

Fluent API DocumentBuilder

DocumentBuilder — это fluent-API для постраничного конструирования PDF-документов с полным контролем над размещением текста, шрифтами, аннотациями, полями форм и элементами содержимого.

Поддержка биндингов (v0.3.38). DocumentBuilder + FluentPageBuilder + EmbeddedFont поставляются в Rust, Python, Node/TypeScript, C#, Go и WASM. Во всех биндингах API одинаков: многостраничная сборка, текст CJK / кириллица / греческий через встраиваемые шрифты, 15 методов аннотаций, 5 типов виджетов AcroForm, графические примитивы (rect, filled_rect, line), шифрование AES-256 и конвейер HTML+CSS.

Быстрый пример

Rust

use pdf_oxide::writer::{DocumentBuilder, PageSize, DocumentMetadata};

let mut builder = DocumentBuilder::new()
    .metadata(DocumentMetadata::new().title("My Document"));

builder
    .page(PageSize::Letter)
        .at(72.0, 720.0)
        .heading(1, "Hello, World!")
        .paragraph("This is a PDF document created with DocumentBuilder.")
        .done();

let bytes = builder.build()?;
std::fs::write("output.pdf", bytes)?;

Python

from pdf_oxide import DocumentBuilder, EmbeddedFont

font = EmbeddedFont.from_file("DejaVuSans.ttf")
pdf = (DocumentBuilder()
    .register_embedded_font("DejaVu", font)
    .a4_page()
        .font("DejaVu", 12).at(72, 720).text("Hello, World!")
        .highlight((1.0, 1.0, 0.0))
    .done()
    .build())
open("output.pdf", "wb").write(pdf)

Node / TypeScript

import { DocumentBuilder, EmbeddedFont } from "pdf-oxide";

const font = await EmbeddedFont.fromFile("DejaVuSans.ttf");
const bytes = new DocumentBuilder()
  .registerEmbeddedFont("DejaVu", font)
  .a4Page()
    .font("DejaVu", 12).at(72, 720).text("Hello, World!")
    .highlight([1.0, 1.0, 0.0])
  .done()
  .build();

C#

using PdfOxide;

using var font = EmbeddedFont.FromFile("DejaVuSans.ttf");
var bytes = DocumentBuilder.Create()
    .RegisterEmbeddedFont("DejaVu", font)
    .A4Page()
        .Font("DejaVu", 12).At(72, 720).Text("Hello, World!")
        .Highlight(1.0, 1.0, 0.0)
    .Done()
    .Build();
File.WriteAllBytes("output.pdf", bytes);

Go (путь CGo; требует CGO_ENABLED=1)

import pdfoxide "github.com/yfedoseev/pdf_oxide/go"

font, _ := pdfoxide.EmbeddedFontFromFile("DejaVuSans.ttf")
defer font.Close()

builder := pdfoxide.NewDocumentBuilder()
builder.RegisterEmbeddedFont("DejaVu", font)
builder.A4Page().
    Font("DejaVu", 12).At(72, 720).Text("Hello, World!").
    Highlight(1.0, 1.0, 0.0).
    Done()
bytes, _ := builder.Build()

WASM (браузер / Node / бандлер — API один и тот же)

import init, { DocumentBuilder, EmbeddedFont } from "pdf-oxide-wasm/web";
await init();

const font = await fetch("/DejaVuSans.ttf").then(r => r.arrayBuffer());
const bytes = new DocumentBuilder()
  .registerEmbeddedFont("DejaVu", EmbeddedFont.fromBytes(new Uint8Array(font), "DejaVu"))
  .a4Page()
    .font("DejaVu", 12).at(72, 720).text("Hello, World!")
  .done()
  .build();

Полный справочник API

DocumentBuilder

DocumentBuilder::new() – Create Builder

let mut builder = DocumentBuilder::new();

.metadata(metadata) – Set Document Metadata

use pdf_oxide::writer::DocumentMetadata;

let mut builder = DocumentBuilder::new()
    .metadata(
        DocumentMetadata::new()
            .title("Report")
            .author("Jane Smith")
            .subject("Q4 Analysis")
            .keywords("finance, quarterly")
            .creator("MyApp")
    );

.page(size) – Add a Page

Возвращает FluentPageBuilder для добавления содержимого на страницу. Вызовите .done() по завершении.

use pdf_oxide::writer::PageSize;

builder.page(PageSize::A4)
    .at(72.0, 770.0)
    .text("Hello")
    .done();

.letter_page() / .a4_page() – Convenience Page Methods

builder.letter_page().text("US Letter page").done();
builder.a4_page().text("A4 page").done();

.build() – Generate PDF Bytes

let bytes: Vec<u8> = builder.build()?;

.save(path) – Build and Save to File

builder.save("output.pdf")?;

.save_encrypted(path, user_pw, owner_pw) – Шифрование AES-256

Добавлено в v0.3.38. Доступно во всех биндингах.

DocumentBuilder::new()
    .a4_page().text("secret").done()
    .save_encrypted("out.pdf", "user-pw", "owner-pw")?;
(DocumentBuilder()
    .a4_page().text("secret").done()
    .save_encrypted("out.pdf", "user-pw", "owner-pw"))
DocumentBuilder.Create()
    .A4Page().Text("secret").Done()
    .SaveEncrypted("out.pdf", "user-pw", "owner-pw");

Также доступно: .to_bytes_encrypted(user_pw, owner_pw) — возвращает зашифрованный PDF в памяти; .save_with_encryption(path, algorithm, permissions, user_pw, owner_pw) (Rust) — произвольный алгоритм и флаги прав доступа.

DocumentMetadata

Конструктор метаданных уровня документа.

Method Description
.title(s) Установить заголовок документа
.author(s) Установить автора документа
.subject(s) Установить тему документа
.keywords(s) Установить ключевые слова документа
.creator(s) Установить приложение-создатель

FluentPageBuilder

Возвращается builder.page(size). Все методы возвращают self для цепочки вызовов (кроме .done()).

Текст и позиционирование

Method Description
.at(x, y) Установить позицию курсора (пунктах от нижнего левого угла)
.text(s) Добавить текст в текущей позиции курсора
.heading(level, s) Добавить заголовок (1-6, с соответствующим шрифтом)
.paragraph(s) Добавить абзац с автоматическим переносом слов
.font(name, size) Установить шрифт для последующего текста
.text_config(config) Установить полную конфигурацию текста
.space(points) Добавить вертикальный пробел
.horizontal_rule() Добавить горизонтальную разделительную линию
.element(elem) Добавить необработанный ContentElement
.elements(vec) Добавить несколько необработанных элементов содержимого

Аннотации

Method Description
.link_url(url) Привязать последний текстовый элемент к URL
.link_page(page_index) Привязать последний текст к внутренней странице
.link_named(destination) Привязать к именованному назначению
.highlight(color) Выделить последний текст (RGB-кортеж)
.underline(color) Подчеркнуть последний текст
.strikeout(color) Зачеркнуть последний текст
.squiggly(color) Волнисто подчеркнуть последний текст
.sticky_note(text) Добавить стикер в позиции курсора
.sticky_note_with_icon(text, icon) Добавить стикер с определённой иконкой
.sticky_note_at(x, y, text) Добавить стикер в определённой позиции
.stamp(stamp_type) Добавить штамп в позиции курсора
.stamp_at(rect, stamp_type) Добавить штамп в определённом прямоугольнике
.freetext(rect, text) Добавить аннотацию свободного текста
.freetext_styled(rect, text, font, size) Добавить стилизованную аннотацию свободного текста
.watermark(text) Добавить диагональный водяной знак на странице
.watermark_confidential() Добавить предустановленный водяной знак «КОНФИДЕНЦИАЛЬНО»
.watermark_draft() Добавить предустановленный водяной знак «ЧЕРНОВИК»
.watermark_custom(watermark) Добавить пользовательскую аннотацию водяного знака
.add_annotation(annotation) Добавить аннотацию любого типа

Виджеты AcroForm

Добавлены во все биндинги в v0.3.38. Все координаты — в пунктах PDF от нижнего левого угла страницы.

Метод Описание
.text_field(name, x, y, w, h, default_value=None) Однострочное поле ввода
.checkbox(name, x, y, w, h, checked) Флажок
.combo_box(name, x, y, w, h, options, selected=None) Выпадающий список
.radio_group(name, buttons, selected=None) Группа радиокнопок; buttons — список (export_value, x, y, w, h)
.push_button(name, x, y, w, h, caption) Кнопка с подписью
(DocumentBuilder()
    .a4_page()
        .text_field("name", 150, 680, 200, 20, "Jane Doe")
        .checkbox("subscribe", 72, 650, 15, 15, True)
        .combo_box("country", 150, 620, 200, 20, ["US", "UK", "DE"], "US")
        .radio_group("tier", [("free", 72, 590, 15, 15), ("pro", 120, 590, 15, 15)], "pro")
        .push_button("submit", 72, 540, 80, 25, "Submit")
    .done()
    .save("form.pdf"))

Графические примитивы

Добавлены во все биндинги в v0.3.38: rect(x, y, w, h) (только обводка), filled_rect(x, y, w, h, color) (заливка RGB-кортежем) и line(x1, y1, x2, y2). Работают в той же цепочке FluentPageBuilder; достаточно для фона форм, разделителей и простых рамок таблиц.

Полноценный контроль над путями / паттернами / градиентами / ExtGState — через ContentStreamBuilder (только Rust — см. Графика, паттерны и шейдинги).

.done() – Finish Page

Возвращает управление DocumentBuilder.

builder.page(PageSize::Letter)
    .at(72.0, 720.0)
    .text("Content")
    .done();  // Back to builder

TextConfig

Конфигурация для рендеринга текста.

use pdf_oxide::writer::TextConfig;

let config = TextConfig {
    font: "Times-Roman".to_string(),
    size: 14.0,
    align: TextAlign::Center,
    line_height: 1.5,
};
Field Type Default
font String "Helvetica"
size f32 12.0
align TextAlign Left
line_height f32 1.2

PageSize

Variant Width x Height (points)
Letter 612 x 792
A4 595 x 842
Legal 612 x 1008
A3 842 x 1190
Custom(w, h) Custom dimensions

Продвинутые примеры

Многостраничный документ с аннотациями

use pdf_oxide::writer::{
    DocumentBuilder, DocumentMetadata, PageSize, StampType
};

let mut builder = DocumentBuilder::new()
    .metadata(
        DocumentMetadata::new()
            .title("Annotated Report")
            .author("Review Team")
    );

// Cover page
builder.page(PageSize::Letter)
    .at(72.0, 600.0)
    .font("Helvetica-Bold", 28.0)
    .text("Annual Review 2025")
    .font("Helvetica", 14.0)
    .space(20.0)
    .text("Prepared by the Review Team")
    .watermark_draft()
    .done();

// Content page with annotations
builder.page(PageSize::Letter)
    .at(72.0, 720.0)
    .heading(1, "Executive Summary")
    .paragraph(
        "Revenue increased 18% year-over-year, driven by expansion \
         into new markets and strong retention rates."
    )
    .text("See full financial details")
    .link_page(2)  // Link to page 3 (0-indexed)
    .space(12.0)
    .heading(2, "Key Findings")
    .text("Customer satisfaction reached an all-time high.")
    .highlight((1.0, 1.0, 0.0))  // Yellow highlight
    .sticky_note("Verify this claim with latest survey data")
    .paragraph(
        "Operating costs were reduced through automation initiatives, \
         achieving a 15% improvement in operational efficiency."
    )
    .stamp(StampType::ForComment)
    .done();

// Data page
builder.page(PageSize::Letter)
    .at(72.0, 720.0)
    .heading(1, "Financial Details")
    .paragraph("Detailed breakdown of revenue by segment...")
    .horizontal_rule()
    .paragraph("North America: $82M (+12%)")
    .paragraph("Europe: $41M (+28%)")
    .paragraph("Asia-Pacific: $19M (+35%)")
    .done();

builder.save("annotated_report.pdf")?;

Точное позиционирование текста

use pdf_oxide::writer::{DocumentBuilder, PageSize};

let mut builder = DocumentBuilder::new();

builder.page(PageSize::Letter)
    // Title at top center area
    .at(200.0, 740.0)
    .font("Helvetica-Bold", 20.0)
    .text("Certificate of Completion")

    // Recipient name
    .at(200.0, 620.0)
    .font("Times-Roman", 16.0)
    .text("Awarded to: Jane Smith")

    // Details at specific positions
    .at(72.0, 500.0)
    .font("Helvetica", 12.0)
    .text("For successfully completing the Advanced Rust Programming course.")

    .at(72.0, 450.0)
    .text("Date: November 15, 2025")

    .at(350.0, 450.0)
    .text("Instructor: Dr. Alan Turing")

    .horizontal_rule()

    .at(72.0, 380.0)
    .font("Helvetica", 9.0)
    .text("Certificate ID: CERT-2025-00042")

    .done();

builder.save("certificate.pdf")?;

Связанные страницы