How-to guides/XFA Forms

Parse and fill XFA dynamic forms in Rust

XFA forms are embedded XML applications inside a PDF. PDFluent can parse the XFA data packet, read field values, and write new values back to the document.

rust
use pdfluent::{PdfDocument, XfaForm};

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

    form.set_field("EmployeeName", "Ada Lovelace")?;
    form.set_field("EmployeeId", "EMP-1815")?;
    form.set_field("Department", "Engineering")?;

    doc.save("filled-form.pdf")?;
    Ok(())
}
Install:cargo add pdfluentDownload SDK →

Step by step

1

Add PDFluent with the xfa feature

XFA support is in the xfa feature flag. It includes the XML parser and the XFA data packet writer.

rust
# Cargo.toml
[dependencies]
pdfluent = { version = "0.9", features = ["xfa"] }
2

Open the PDF and check for an XFA form

Not every PDF contains an XFA form. Use has_xfa() to check before calling xfa_form().

rust
use pdfluent::PdfDocument;

let doc = PdfDocument::open("dynamic-form.pdf")?;

if doc.has_xfa() {
    println!("XFA form detected");
} else {
    println!("No XFA form found in this document");
}
3

Enumerate all form fields

Call xfa_form() to get a read-only view. Iterate fields() to discover field names and their current values.

rust
let form = doc.xfa_form()?;

for field in form.fields() {
    println!(
        "name={:?}  type={:?}  value={:?}",
        field.name(),
        field.field_type(),
        field.value()
    );
}
4

Set field values

Use xfa_form_mut() to get a mutable handle. set_field() accepts any value that implements Into<String>.

rust
let mut form = doc.xfa_form_mut()?;

form.set_field("EmployeeName", "Ada Lovelace")?;
form.set_field("StartDate", "2024-03-01")?;
form.set_field("FullTime", "true")?;   // checkbox
5

Save the filled document

Save writes the updated XFA data packet back into the PDF structure. The output is a valid PDF with the new field values baked in.

rust
doc.save("filled-form.pdf")?;
println!("Saved filled-form.pdf");

Notes and tips

  • XFA forms come in two variants: static XFA and dynamic XFA. PDFluent supports both for reading. Dynamic XFA reflow is supported for simple layouts.
  • XFA forms were deprecated in PDF 2.0. Many modern viewers have dropped support. Consider converting to AcroForm for maximum compatibility.
  • Field names in XFA are XPath expressions. Short names like "EmployeeName" work for flat forms. Nested subforms require a full path like "Root.PersonData.Name".
  • PDFluent preserves all XFA streams not modified by set_field(), so signature fields and static content are not affected.

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