Guides, code examples, and API reference for PDF processing across six language channels.
Source-available on GitHub
Common operations to get started
use pdfluent::PdfDocument;
let doc = PdfDocument::open("invoice.pdf")?;
// The full text, in reading order.
let text = doc.extract_text()?;
println!("{text}");
// Or per page.
for n in 0..doc.page_count() {
println!("--- page {} ---", n + 1);
println!("{}", doc.page(n)?.text()?);
}use pdfluent::PdfDocument;
let mut doc = PdfDocument::open("tax_return.pdf")?;
// The form model: one row per logical field.
let model = doc.xfa_form_model()?;
for field in &model.fields {
println!("{} = {:?}", field.name, field.value);
}
// Fill by name.
doc.set_xfa_field_value("form1.name", pdfluent::xfa::XfaFieldValue::Text("Smith"))?;use pdfluent::{PdfAProfile, PdfDocument};
let doc = PdfDocument::open("legacy.pdf")?;
let report = doc.validate_pdfa(PdfAProfile::A2b)?;
if report.is_compliant() {
println!("conforms to PDF/A-2b");
} else {
for violation in &report.violations {
println!("{violation:?}");
}
}use pdfluent::signer::{PadesProfile, Pkcs12Signer, SignOptions};
use pdfluent::PdfDocument;
let mut doc = PdfDocument::open("contract.pdf")?;
let signer = Pkcs12Signer::from_pfx_file("cert.p12", "password")?;
// SignOptions::new() asks for PAdES B-LT, which needs a document security
// store this build cannot write. Choose the profile you can honour.
let opts = SignOptions::new()
.profile(PadesProfile::BasicSignature)
.reason("Approved");
doc.sign(&signer, opts)?;
doc.save("contract-signed.pdf")?;85+ step-by-step guides covering every PDF operation in Rust — merging, signing, OCR, PDF/A, XFA, and more.
Browse all guides →Error codes with explanations, root causes, and fixes. Covers common issues in iText, PDFBox, IronPDF migrations too.
Browse errors →The SDK is free and complete under the AGPLv3 — every feature, no key, nothing that expires. If you cannot publish your own source, tell us what you are building and we will say which licence covers it.
Check your licence →