Build a PDF programmatically. Add pages, text, images, and set document metadata without any source file.
use pdfluent::{PdfDocument, Page, PageSize, TextOptions, Color, Font};
fn main() -> pdfluent::Result<()> {
let mut doc = PdfDocument::new();
doc.set_title("Quarterly Report Q1 2024");
doc.set_author("Finance Team");
let mut page = Page::new(PageSize::A4);
page.add_text(
"Quarterly Report",
TextOptions {
x: 50.0,
y: 780.0,
font_size: 28.0,
color: Color::rgb(10, 10, 10),
..TextOptions::default()
},
)?;
page.add_text(
"Q1 2024 — Revenue: EUR 1,240,000",
TextOptions {
x: 50.0,
y: 740.0,
font_size: 14.0,
color: Color::rgb(80, 80, 80),
..TextOptions::default()
},
)?;
doc.add_page(page);
doc.save("quarterly-report.pdf")?;
Ok(())
}Creating PDFs from scratch requires only the base crate.
# Cargo.toml
[dependencies]
pdfluent = "0.9"PdfDocument::new() creates an empty PDF 1.7 document. Set XMP and DocInfo metadata before adding content.
use pdfluent::PdfDocument;
let mut doc = PdfDocument::new();
doc.set_title("Quarterly Report Q1 2024");
doc.set_author("Finance Team");
doc.set_subject("Financial summary");
doc.set_creator("pdfluent 0.9");Page::new() accepts a PageSize enum or custom dimensions in points. Common sizes: A4 is 595x842 pt, US Letter is 612x792 pt.
use pdfluent::{Page, PageSize};
// Standard A4
let mut page = Page::new(PageSize::A4);
// Custom size: 200 x 100 mm
let mut page = Page::new(PageSize::custom_mm(200.0, 100.0));
println!("Page: {}x{} pt", page.width(), page.height());PDF coordinates start at the bottom-left corner. Use font_size, color, and an optional embedded font to control appearance.
use pdfluent::{TextOptions, Color};
page.add_text(
"Invoice #INV-2024-042",
TextOptions {
x: 50.0,
y: 780.0,
font_size: 22.0,
color: Color::black(),
..TextOptions::default()
},
)?;
page.add_text(
"Due: 2024-05-01",
TextOptions {
x: 50.0,
y: 750.0,
font_size: 11.0,
color: Color::rgb(100, 100, 100),
..TextOptions::default()
},
)?;Use the page drawing API for visual structure. Add a horizontal rule under a header or a bounding box around a table.
use pdfluent::{Image, ImagePosition, Rect, StrokeOptions};
// Horizontal line
page.draw_line(50.0, 720.0, 545.0, 720.0, StrokeOptions {
width: 1.0,
color: Color::rgb(200, 200, 200),
})?;
// Filled rectangle
page.draw_rect(Rect {
x: 50.0, y: 100.0, width: 495.0, height: 40.0,
}, Color::rgb(240, 245, 255), None)?;
// Image
let logo = Image::from_file("logo.png")?;
page.add_image(&logo, ImagePosition {
x: 400.0, y: 780.0, width: 100.0, height: 40.0,
})?;
// Add page to document and save
doc.add_page(page);
doc.save("invoice.pdf")?;No JVM, no runtime, no DLL dependencies. Ships as a single native binary or WASM module.
Rust's ownership model prevents buffer overflows and use-after-free. No segfaults in PDF parsing.
Same code runs server-side, in Docker, on AWS Lambda, on Cloudflare Workers, or in the browser via WASM.