Skip to content

Fluent-API von DocumentBuilder

DocumentBuilder ist eine Fluent-API zum seitenweisen Erstellen von PDF-Dokumenten mit voller Kontrolle über Textplatzierung, Schriftarten, Anmerkungen, Formularfelder und Inhaltselemente.

Binding-Abdeckung (v0.3.38). DocumentBuilder + FluentPageBuilder + EmbeddedFont sind in Rust, Python, Node/TypeScript, C#, Go und WASM verfügbar. Jedes Binding stellt denselben Funktionsumfang bereit: mehrseitige Konstruktion, CJK-/Kyrillisch-/Griechisch-Text über eingebettete Schriftarten, 15 Anmerkungsmethoden, 5 AcroForm-Widget-Typen, Grafikprimitive (rect, filled_rect, line), AES-256-Verschlüsselung sowie die HTML+CSS-Pipeline.

Schnelles Beispiel

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-Pfad; erfordert 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 (Browser / Node / Bundler — dieselbe 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();

C++

#include <pdf_oxide/pdf_oxide.hpp>

auto font = pdf_oxide::EmbeddedFont::from_file("DejaVuSans.ttf");
auto builder = pdf_oxide::DocumentBuilder::create();
builder.register_embedded_font("DejaVu", font);
builder.a4_page()
    .font("DejaVu", 12).at(72, 720).text("Hello, World!")
    .highlight(1.0, 1.0, 0.0)
    .done();
std::vector<std::uint8_t> bytes = builder.build();

Swift

import PdfOxide

let font = try EmbeddedFont.fromFile("DejaVuSans.ttf")
let builder = try DocumentBuilder.create()
try builder.registerEmbeddedFont("DejaVu", font)
let page = try builder.a4Page()
try page.font("DejaVu", 12).at(72, 720).text("Hello, World!")
    .highlight(1.0, 1.0, 0.0)
    .done()
let bytes = try builder.build()

Dart

import 'package:pdf_oxide/pdf_oxide.dart';

final font = EmbeddedFont.fromFile('DejaVuSans.ttf');
final builder = DocumentBuilder.create();
builder.registerEmbeddedFont('DejaVu', font);
builder.a4Page()
    .font('DejaVu', 12.0).at(72.0, 720.0).text('Hello, World!')
    .highlight(1.0, 1.0, 0.0)
    .done();
final bytes = builder.build();

R

library(pdfoxide)

font <- pdf_embedded_font_from_file("DejaVuSans.ttf")
b    <- pdf_builder_create()
pdf_builder_register_embedded_font(b, "DejaVu", font)
pg <- pdf_builder_a4_page(b)
pdf_page_font(pg, "DejaVu", 12)
pdf_page_at(pg, 72, 720)
pdf_page_builder_text(pg, "Hello, World!")
pdf_page_highlight(pg, 1.0, 1.0, 0.0)
pdf_page_done(pg)
bytes <- pdf_builder_build(b)

Julia

using PdfOxide

emb = embedded_font_from_file("DejaVuSans.ttf")
b   = DocumentBuilder()
register_embedded_font(b, "DejaVu", emb)
pg = a4_page(b)
font(pg, "DejaVu", 12)
at(pg, 72, 720)
text(pg, "Hello, World!")
highlight(pg, 1.0, 1.0, 0.0)
done(pg)
bytes = build(b)

Zig

const pdf_oxide = @import("pdf_oxide");
const a = std.heap.page_allocator;

var font = try pdf_oxide.EmbeddedFont.fromFile("DejaVuSans.ttf");
var builder = try pdf_oxide.DocumentBuilder.create();
try builder.registerEmbeddedFont("DejaVu", &font);
var page = try builder.a4Page();
try page.font("DejaVu", 12);
try page.at(72, 720);
try page.text("Hello, World!");
try page.highlight(1.0, 1.0, 0.0);
try page.done();
const bytes = try builder.build(a);

Objective-C

#import "POXPdfOxide.h"
NSError *err = nil;

POXEmbeddedFont *font = [POXEmbeddedFont fromPath:@"DejaVuSans.ttf" error:&err];
POXDocumentBuilder *builder = [POXDocumentBuilder createWithError:&err];
[builder registerEmbeddedFont:@"DejaVu" font:font error:&err];
POXPageBuilder *page = [builder a4PageWithError:&err];
[page font:@"DejaVu" size:12 error:&err];
[page at:72 y:720 error:&err];
[page text:@"Hello, World!" error:&err];
[page highlightR:1.0 g:1.0 b:0.0 error:&err];
[page done:&err];
NSData *bytes = [builder buildWithError:&err];

Elixir

{:ok, font} = PdfOxide.font_from_file("DejaVuSans.ttf")
{:ok, db}   = PdfOxide.builder()
:ok = PdfOxide.builder_register_embedded_font(db, "DejaVu", font)
{:ok, page} = PdfOxide.builder_a4_page(db)
:ok = PdfOxide.page_font(page, "DejaVu", 12)
:ok = PdfOxide.page_at(page, 72, 720)
:ok = PdfOxide.page_text(page, "Hello, World!")
:ok = PdfOxide.page_highlight(page, 1.0, 1.0, 0.0)
:ok = PdfOxide.page_done(page)
{:ok, bytes} = PdfOxide.builder_build(db)

Vollständige API-Referenz

DocumentBuilder

DocumentBuilder::new() – Builder erstellen

let mut builder = DocumentBuilder::new();

.metadata(metadata) – Dokumentmetadaten festlegen

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) – Eine Seite hinzufügen

Gibt einen FluentPageBuilder zurück, um der Seite Inhalt hinzuzufügen. Rufen Sie .done() auf, wenn Sie fertig sind.

use pdf_oxide::writer::PageSize;

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

.letter_page() / .a4_page() – Praktische Seitenmethoden

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

.build() – PDF-Bytes erzeugen

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

.save(path) – Erstellen und in Datei speichern

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

.save_encrypted(path, user_pw, owner_pw) – AES-256-Verschlüsselung

In v0.3.38 hinzugefügt. In jedem Binding verfügbar.

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");

Ebenfalls verfügbar: .to_bytes_encrypted(user_pw, owner_pw) für die Ausgabe im Speicher; .save_with_encryption(path, algorithm, permissions, user_pw, owner_pw) (Rust) für einen benutzerdefinierten Algorithmus und Flags pro Berechtigung.

DocumentMetadata

Builder für Metadaten auf Dokumentebene.

Methode Beschreibung
.title(s) Dokumenttitel festlegen
.author(s) Dokumentautor festlegen
.subject(s) Dokumentbetreff festlegen
.keywords(s) Schlüsselwörter festlegen
.creator(s) Erstellungsanwendung festlegen

FluentPageBuilder

Wird von builder.page(size) zurückgegeben. Alle Methoden geben self zur Verkettung zurück (außer .done()).

Text und Positionierung

Methode Beschreibung
.at(x, y) Cursorposition festlegen (Punkte ab unten links)
.text(s) Text an der aktuellen Cursorposition hinzufügen
.heading(level, s) Überschrift hinzufügen (1–6, mit passender Schriftart)
.paragraph(s) Absatz mit automatischem Zeilenumbruch hinzufügen
.font(name, size) Schriftart für nachfolgenden Text festlegen
.text_config(config) Vollständige Textkonfiguration festlegen
.space(points) Vertikalen Abstand hinzufügen
.horizontal_rule() Horizontale Trennlinie hinzufügen
.element(elem) Ein rohes ContentElement hinzufügen
.elements(vec) Mehrere rohe Inhaltselemente hinzufügen

Anmerkungen

Methode Beschreibung
.link_url(url) Das letzte Textelement mit einer URL verknüpfen
.link_page(page_index) Den letzten Text mit einer internen Seite verknüpfen
.link_named(destination) Mit einem benannten Ziel verknüpfen
.highlight(color) Den letzten Text hervorheben (RGB-Tupel)
.underline(color) Den letzten Text unterstreichen
.strikeout(color) Den letzten Text durchstreichen
.squiggly(color) Den letzten Text wellenförmig unterstreichen
.sticky_note(text) Haftnotiz an der Cursorposition hinzufügen
.sticky_note_with_icon(text, icon) Haftnotiz mit bestimmtem Symbol hinzufügen
.sticky_note_at(x, y, text) Haftnotiz an bestimmter Position hinzufügen
.stamp(stamp_type) Stempel an der Cursorposition hinzufügen
.stamp_at(rect, stamp_type) Stempel in bestimmtem Rechteck hinzufügen
.freetext(rect, text) Freitext-Anmerkung hinzufügen
.freetext_styled(rect, text, font, size) Formatierte Freitext-Anmerkung hinzufügen
.watermark(text) Diagonales Wasserzeichen über die Seite hinzufügen
.watermark_confidential() Vordefiniertes “CONFIDENTIAL”-Wasserzeichen hinzufügen
.watermark_draft() Vordefiniertes “DRAFT”-Wasserzeichen hinzufügen
.watermark_custom(watermark) Benutzerdefinierte Wasserzeichen-Anmerkung hinzufügen
.add_annotation(annotation) Beliebigen Anmerkungstyp hinzufügen

AcroForm-Widgets

In v0.3.38 in allen Bindings hinzugefügt. Alle Positionen sind in PDF-Punkten vom Ursprung unten links der Seite angegeben.

Methode Beschreibung
.text_field(name, x, y, w, h, default_value=None) Einzeiliges Texteingabefeld
.checkbox(name, x, y, w, h, checked) Kontrollkästchen-Widget
.combo_box(name, x, y, w, h, options, selected=None) Dropdown-Auswahl
.radio_group(name, buttons, selected=None) Optionsfeldgruppe; buttons ist eine Liste von (export_value, x, y, w, h)
.push_button(name, x, y, w, h, caption) Anklickbare Schaltfläche mit Beschriftung
(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"))

Grafikprimitive

In v0.3.38 in allen Bindings hinzugefügt: rect(x, y, w, h) (nur Kontur), filled_rect(x, y, w, h, color) (gefüllt mit einem RGB-Tupel) und line(x1, y1, x2, y2). Sie laufen über dieselbe FluentPageBuilder-Kette und reichen für Formularhintergründe, Trennlinien und einfache Tabellenränder aus.

Für vollständige Pfad-/Muster-/Verlauf-/ExtGState-Kontrolle verwenden Sie den ContentStreamBuilder (nur Rust — siehe Grafiken, Muster und Schattierungen).

.done() – Seite abschließen

Gibt die Kontrolle an den DocumentBuilder zurück.

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

TextConfig

Konfiguration für das Rendern von Text.

use pdf_oxide::writer::TextConfig;

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

PageSize

Variante Breite x Höhe (Punkte)
Letter 612 x 792
A4 595 x 842
Legal 612 x 1008
A3 842 x 1190
Custom(w, h) Benutzerdefinierte Maße

Erweiterte Beispiele

Mehrseitiges Dokument mit Anmerkungen

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")?;

Präzise Textpositionierung

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")?;

Verwandte Seiten