Extract one or more page ranges from a PDF and write each range to a separate file. Useful for splitting chapters, invoices, or reports.
use pdfluent::{PdfDocument, PageRange};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let doc = PdfDocument::open("report.pdf")?;
doc.split_by_ranges(&[
PageRange::new(1, 10),
PageRange::new(11, 20),
PageRange::new(21, doc.page_count()),
])
.write_files("chapter_{n}.pdf")?;
Ok(())
}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.
use pdfluent::PdfDocument;
let doc = PdfDocument::open("quarterly_report.pdf")?;
println!("Source has {} pages", doc.page_count());Create PageRange values for each segment. Pages are 1-indexed. Ranges can overlap if you need the same page in multiple output files.
use pdfluent::PageRange;
let ranges = vec![
PageRange::new(1, 5), // cover + intro
PageRange::new(6, 18), // body
PageRange::new(19, 22), // appendix
];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.
doc.split_by_ranges(&ranges)
.write_files("segment_{n}.pdf")?;
// Produces: segment_1.pdf, segment_2.pdf, segment_3.pdfWhen you need specific filenames, pass a slice of paths with the same length as the ranges slice.
let output_paths = ["cover.pdf", "body.pdf", "appendix.pdf"];
doc.split_by_ranges(&ranges)
.write_named_files(&output_paths)?;If you need to serve the split files over HTTP without touching disk, use to_bytes_vec() instead.
let buffers: Vec<Vec<u8>> = doc
.split_by_ranges(&ranges)
.to_bytes_vec()?;
for (i, buf) in buffers.iter().enumerate() {
println!("Segment {}: {} bytes", i + 1, buf.len());
}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.