How-to guides/Merge & Split

Split a PDF by page range in Rust

Extract one or more page ranges from a PDF and write each range to a separate file. Useful for splitting chapters, invoices, or reports.

rust
use pdfluent::PdfDocument;

fn main() -> pdfluent::Result<()> {
    let doc = PdfDocument::open("report.pdf")?;
    for (i, page) in doc.split_pages()?.into_iter().enumerate() {
        page.save(format!("page-{}.pdf", i + 1))?;
    }
    Ok(())
}

Step by step

1

Open the source document

Load the PDF you want to split. PDFluent reads the file lazily, so opening a 500-page document uses minimal memory until pages are accessed.

rust
use pdfluent::PdfDocument;

let doc = PdfDocument::open("quarterly_report.pdf")?;
println!("Source has {} pages", doc.page_count());
2

Define page ranges

Create PageRange values for each segment. Pages are 1-indexed. Ranges can overlap if you need the same page in multiple output files.

rust
// Ranges to extract (0-based, end-exclusive)
let ranges = [0..5usize, 5..18, 18..22];
3

Split and write to separate files

Pass the ranges to split_by_ranges(). Use {n} in the output pattern for the range index, or provide a Vec of explicit output paths.

rust
for (i, range) in ranges.iter().enumerate() {
    doc.extract_pages(range.clone())?.save(format!("segment_{}.pdf", i + 1))?;
}
// Produces: segment_1.pdf, segment_2.pdf, segment_3.pdf
4

Use explicit output names

When you need specific filenames, pass a slice of paths with the same length as the ranges slice.

rust
let names = ["cover.pdf", "body.pdf", "appendix.pdf"];
for (range, name) in ranges.iter().zip(names) {
    doc.extract_pages(range.clone())?.save(name)?;
}
5

Split into in-memory buffers

If you need to serve the split files over HTTP without touching disk, use to_bytes_vec() instead.

rust
for (i, range) in ranges.iter().enumerate() {
    let bytes = doc.extract_pages(range.clone())?.to_bytes()?;
    println!("Segment {}: {} bytes", i + 1, bytes.len());
}

Notes and tips

  • Page indices are 1-based. Passing 0 returns an error.
  • Ranges that extend past the last page are clamped to the last page automatically.
  • Bookmarks pointing to pages outside a range are dropped in that output file.
  • AcroForm fields on pages that fall within a range are included in the corresponding output file.

Why PDFluent for this

Pure Rust

No JVM, no runtime, no DLL dependencies. Ships as a single native binary or WASM module.

Memory safe

Rust's ownership model prevents buffer overflows and use-after-free. No segfaults in PDF parsing.

Runs anywhere

Same code runs server-side, in Docker, on AWS Lambda, on Cloudflare Workers, or in the browser via WASM.

Frequently asked questions