Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apache/pdfbox/llms.txt
Use this file to discover all available pages before exploring further.
PDF interactive forms are stored as AcroForms — a tree of PDField objects attached to the document catalog. PDFBox exposes this structure through PDAcroForm, which lets you enumerate fields, read their values, set new values, and flatten the form into static page content. Understanding field names is key: nested fields use dot-separated fully qualified names such as "fieldsContainer.nestedSampleField".
Use acroForm.getField("fullyQualifiedName") to access nested fields directly. The fully qualified name is the dot-joined path from the root of the field tree to the target field — for example, "address.city".
Load the document and retrieve the PDAcroForm from the document catalog. getFields() returns the top-level fields; nested fields are children of PDNonTerminalField nodes.
PDDocument pdf = Loader.loadPDF(new File("form.pdf"));
PDDocumentCatalog docCatalog = pdf.getDocumentCatalog();
PDAcroForm acroForm = docCatalog.getAcroForm();
List<PDField> fields = acroForm.getFields();
System.out.println(fields.size() + " top-level fields were found on the form");
for (PDField field : fields)
{
String partialName = field.getPartialName();
String fieldValue = field.getValueAsString();
System.out.println(partialName + " = " + fieldValue
+ ", type=" + field.getClass().getName());
if (field instanceof PDNonTerminalField)
{
for (PDField child : ((PDNonTerminalField) field).getChildren())
{
System.out.println(" child: " + child.getPartialName());
}
}
}
Filling a text field
Look up a field by its fully qualified name, cast it to PDTextField, and call setValue. PDFBox regenerates the field’s appearance stream automatically.
try (PDDocument pdfDocument = Loader.loadPDF(new File("form.pdf")))
{
PDAcroForm acroForm = pdfDocument.getDocumentCatalog().getAcroForm();
if (acroForm != null)
{
// top-level field
PDTextField field = (PDTextField) acroForm.getField("sampleField");
field.setValue("Text Entry");
// nested field accessed by fully qualified name
field = (PDTextField) acroForm.getField("fieldsContainer.nestedSampleField");
field.setValue("Text Entry");
}
pdfDocument.save("filled.pdf");
}
Building an AcroForm requires a PDAcroForm instance, a font resource registered under a known name (Acrobat uses /Helv), and one or more PDTextField widgets linked to a page annotation.
try (PDDocument document = new PDDocument())
{
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
// register font resource
PDFont font = new PDType1Font(FontName.HELVETICA);
PDResources resources = new PDResources();
resources.put(COSName.HELV, font);
// create AcroForm and attach to document
PDAcroForm acroForm = new PDAcroForm(document);
document.getDocumentCatalog().setAcroForm(acroForm);
acroForm.setDefaultResources(resources);
acroForm.setDefaultAppearance("/Helv 0 Tf 0 g"); // auto-size font
// create text field
PDTextField textBox = new PDTextField(acroForm);
textBox.setPartialName("SampleField");
textBox.setDefaultAppearance("/Helv 12 Tf 0 0 1 rg"); // 12pt blue
textBox.setQ(PDVariableText.QUADDING_CENTERED);
acroForm.getFields().add(textBox);
// attach widget annotation to page
PDAnnotationWidget widget = textBox.getWidgets().get(0);
widget.setRectangle(new PDRectangle(50, 750, 200, 50));
widget.setPage(page);
widget.setPrinted(true);
page.getAnnotations().add(widget);
// set an initial value
textBox.setValue("Sample field content");
document.save("SimpleForm.pdf");
}
Flattening merges field appearances into the page content stream and removes the interactive form structure, producing a static document that renders consistently across all viewers.
try (PDDocument document = Loader.loadPDF(new File("filled.pdf")))
{
PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
if (acroForm != null)
{
acroForm.flatten();
}
document.save("flattened.pdf");
}