Generate, merge, split, shrink, and print PDFs

A practical guide for developers using the PDFluent SDK to build document automation and processing pipelines in Rust.

Automate PDF generation and processing at scale.

Generate thousands of invoices, process incoming PDFs, fill forms, add watermarks, and run PDF pipelines in CI/CD — all from a single Rust binary with no external dependencies.

rust
use pdfluent::{PdfDocument, WatermarkOptions};

fn main() -> pdfluent::Result<()> {
    let mut doc = PdfDocument::open("template.pdf")?;

    doc.form_mut()
        .set_text("customer_name", "ACME Corp")?
        .set_text("date", "2026-01-15")?;

    doc.add_watermark("PROCESSED", WatermarkOptions::centered().opacity(0.15))?;
    doc.save("filled.pdf")?;
    Ok(())
}

Every PDF operation your pipeline needs.

Automate PDF document processing at scale with PDFluent: extract text, split/merge pages, apply redactions, and convert to PDF/A — all in pure Rust.

rust
use pdfluent::PdfDocument;

fn main() -> pdfluent::Result<()> {
    let doc = PdfDocument::open("invoice.pdf")?;

    // Positioned text blocks: text + bounding box + page
    for block in doc.text_with_layout()? {
        println!("p{} {:?} {}", block.page, block.bbox, block.text);
    }
    Ok(())
}

Merge and split. Correctly.

Lossless PDF merge and split in Rust — bookmarks, page labels, and named destinations preserved.

rust
use pdfluent::{PdfDocument, PdfMerger, BookmarkMergeStrategy};

fn main() -> pdfluent::Result<()> {
    let merged = PdfMerger::new()
        .add(PdfDocument::open("chapter1.pdf")?)
        .add(PdfDocument::open("chapter2.pdf")?)
        .add(PdfDocument::open("chapter3.pdf")?)
        .with_bookmarks(BookmarkMergeStrategy::Concat)
        .with_page_labels(true)
        .build()?;

    merged.save("book_complete.pdf")?;
    println!("Pages: {}", merged.page_count());
    Ok(())
}

Split PDFs by page, bookmark, or pattern.

Extract pages, split at bookmarks, or divide by content pattern. Batch split thousands of documents with bookmark and label preservation.

rust
use pdfluent::PdfDocument;

fn main() -> pdfluent::Result<()> {
    let doc = PdfDocument::open("report.pdf")?;

    // Split into single-page documents
    for (i, page) in doc.split_pages()?.into_iter().enumerate() {
        page.save(format!("page-{}.pdf", i + 1))?;
    }

    // Or extract a contiguous range (0-based, end-exclusive)
    doc.extract_pages(0..5)?.save("first-five.pdf")?;
    Ok(())
}

Shrink PDFs without quality loss.

Compress images, remove duplicate streams, and optimize cross-reference tables. Reduce file size by 40-80% on typical documents.

rust
use pdfluent::{PdfDocument, CompressOptions};

fn main() -> pdfluent::Result<()> {
    let mut doc = PdfDocument::open("large.pdf")?;

    let report = doc.compress(CompressOptions::strict())?;
    println!("streams compressed: {}", report.streams_compressed);
    println!("streams deduplicated: {}", report.streams_deduplicated);

    doc.save("compressed.pdf")?;
    Ok(())
}

PDF processing that deploys anywhere.

No native dependencies. No JVM. No DLLs. PDFluent runs on Lambda, Cloudflare Workers, and Fly.io straight from a single Rust binary.

rust
use lambda_runtime::{run, service_fn, Error, LambdaEvent};
use pdfluent::PdfDocument;
use serde::{Deserialize, Serialize};

#[derive(Deserialize)]
struct Request {
    /// Base64-encoded PDF bytes
    pdf_b64: String,
}

#[derive(Serialize)]
struct Response {
    page_count: usize,
}

async fn handler(event: LambdaEvent<Request>) -> Result<Response, Error> {
    let bytes = base64::decode(&event.payload.pdf_b64)?;
    let doc = Document::open_bytes(&bytes)?;
    Ok(Response { page_count: doc.page_count() })
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    run(service_fn(handler)).await
}