Tile 2, 4, 6, or 9 source pages onto a single output sheet, useful for printing booklets or handouts.
use pdfluent::{Document, nup::{NUpLayout, NUpOptions}};
fn main() -> pdfluent::Result<()> {
let doc = Document::open("input.pdf")?;
// 2-up: two A4 source pages side by side on one A3 sheet
let opts = NUpOptions::new(NUpLayout::TwoUp);
let output = doc.nup(opts)?;
output.save("2up.pdf")?;
Ok(())
}The source pages are scaled and positioned into the output sheet. The original file is not modified.
let doc = Document::open("input.pdf")?;NUpLayout provides common configurations. Each layout specifies the grid dimensions and the output sheet size.
use pdfluent::nup::NUpLayout;
let layout = NUpLayout::TwoUp; // 1x2 grid, landscape A4
// NUpLayout::FourUp // 2x2 grid, A4
// NUpLayout::SixUp // 2x3 grid, A4
// NUpLayout::NineUp // 3x3 grid, A4
// NUpLayout::Custom { cols: 3, rows: 2, sheet: PageSize::A3 }NUpOptions lets you set the gap between cells and the outer margin in points.
use pdfluent::nup::NUpOptions;
let opts = NUpOptions::new(NUpLayout::FourUp)
.gap(8.0) // 8 pt gap between cells
.margin(20.0); // 20 pt outer marginCall doc.nup(opts) to produce a new Document where each output page contains the specified number of source pages.
let output = doc.nup(opts)?;Write the output file. The page count of the output is ceil(source_pages / n).
println!(
"Input pages: {}, Output pages: {}",
doc.page_count(),
output.page_count(),
);
output.save("nup_output.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.