Once a PDF form has been completed, you may want to prevent further edits without losing the form structure, or remove the interactive fields entirely and produce a final version for delivery or archiving.
These two requirements are usually handled differently. A read-only field remains part of the PDF form and can still be accessed programmatically, while a flattened field is converted into static page content.
This article shows how to make an entire PDF form or an individual field read-only, how to flatten all or selected fields, and when each approach is more appropriate.
Add the Dependency
The examples below use Spire.PDF for Java to work with PDF forms. For Maven projects, add the following repository and dependency to pom.xml:
<repositories>
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.pdf</artifactId>
<version>12.8.6</version>
</dependency>
</dependencies>
Make an Entire PDF Form Read-Only
If the field values still need to be available to later code but users should no longer be able to change them, keep the form structure and mark the form as read-only.
Use PdfFormWidget.setReadOnly() to apply the setting to all fields:
import com.spire.pdf.PdfDocument;
import com.spire.pdf.widget.PdfFormWidget;
public class SetFormReadOnly {
public static void main(String[] args) {
// Load the PDF form
PdfDocument pdf = new PdfDocument();
pdf.loadFromFile("ApplicationForm.pdf");
// Make all form fields read-only
PdfFormWidget form = (PdfFormWidget) pdf.getForm();
form.setReadOnly(true);
// Save the result
pdf.saveToFile("ApplicationForm_ReadOnly.pdf");
pdf.close();
}
}
The fields remain in the PDF after this operation, so the application can still retrieve their names and values or perform other form-related processing later.
Make a Specific PDF Form Field Read-Only
To lock only one field, retrieve the corresponding PdfField and call setReadOnly() on it:
import com.spire.pdf.PdfDocument;
import com.spire.pdf.fields.PdfField;
import com.spire.pdf.widget.PdfFormWidget;
public class SetFieldReadOnly {
public static void main(String[] args) {
PdfDocument pdf = new PdfDocument();
pdf.loadFromFile("ApplicationForm.pdf");
PdfFormWidget form = (PdfFormWidget) pdf.getForm();
// Get the field by its internal name
PdfField field = form.getFieldsWidget().get("RequestAmount");
if (field != null) {
field.setReadOnly(true);
}
pdf.saveToFile("ApplicationForm_PartiallyReadOnly.pdf");
pdf.close();
}
}
One detail that matters in real projects is that the name used in code is the field's internal PDF name, not necessarily the label visible on the page.
A field displayed as Request Amount, for example, may internally be named:
RequestAmount
amount
TextField12
If the template comes from another team or an external source, inspect the available field names first:
PdfFormWidget form = (PdfFormWidget) pdf.getForm();
for (int i = 0; i < form.getFieldsWidget().getCount(); i++) {
PdfField field = form.getFieldsWidget().get(i);
System.out.println(field.getName());
}
For templates that change over time, field names are also safer than hard-coded indexes. Once fields are added or reordered, an index may point to a different field without making the problem immediately obvious.
Flatten All PDF Form Fields
When the PDF no longer needs to behave as an interactive form, the fields can be flattened.
Use isFlatten(true) to flatten the entire form:
import com.spire.pdf.PdfDocument;
public class FlattenForm {
public static void main(String[] args) {
// Load the completed PDF form
PdfDocument pdf = new PdfDocument();
pdf.loadFromFile("ApprovedForm.pdf");
// Flatten all form fields
pdf.getForm().isFlatten(true);
// Save the result
pdf.saveToFile("ApprovedForm_Flattened.pdf");
pdf.close();
}
}
The current appearance of each field is preserved on the page, but text boxes, check boxes, drop-down lists, and other interactive controls are no longer available as fillable fields.
Any logic that still depends on the form structure should therefore run before flattening. This includes reading values, assigning data, validating fields, and exporting form data.
Flatten a Specific PDF Form Field
You can also flatten a single field while leaving the rest of the form interactive.
Retrieve the target PdfField and call setFlatten(true):
import com.spire.pdf.PdfDocument;
import com.spire.pdf.fields.PdfField;
import com.spire.pdf.widget.PdfFormWidget;
public class FlattenField {
public static void main(String[] args) {
PdfDocument pdf = new PdfDocument();
pdf.loadFromFile("ApplicationForm.pdf");
PdfFormWidget form = (PdfFormWidget) pdf.getForm();
// Get the target field
PdfField field = form.getFieldsWidget().get("RequestAmount");
if (field != null) {
field.setFlatten(true);
}
pdf.saveToFile("ApplicationForm_PartiallyFlattened.pdf");
pdf.close();
}
}
This is useful when one part of a form is final but other fields still need to remain editable.
Checking for null is worth keeping in production code. PDF templates are often updated independently of the application, and a renamed or removed field can otherwise turn a simple template change into a NullPointerException.
Read-Only vs. Flattened Form Fields
Both approaches can stop normal user input, but they leave the PDF in very different states.
| Aspect | Read-Only | Flattened |
|---|---|---|
| Interactive field structure preserved | Yes | No |
| User can edit the field normally | No | No |
| Field can still be accessed by name | Yes | No longer appropriate |
| Field properties can be changed later | Yes | No |
| Suitable for ongoing form processing | Yes | Usually not |
| Suitable for final delivery or archiving | Yes | Usually better |
Use read-only fields when the PDF is still part of a larger workflow and your code may need to inspect or process the form later.
Flatten the fields when the form itself is no longer needed and only the final rendered content matters.
Neither option should be treated as a PDF security feature. Setting a field to read-only or flattening it does not prevent the whole document from being edited, copied, or printed. Those requirements belong to PDF permission settings, while tamper detection is better handled with digital signatures.
Practical Considerations
For fixed templates, field names are generally more reliable than field indexes. If templates are maintained outside the development team, it is useful to inspect the internal field names during integration and keep those names in configuration or constants rather than scattering them throughout the codebase.
Flattening should also be one of the last steps in the processing pipeline. Once a final flattened file has been produced, later code should not assume that the original form structure is still available.
The rendered result deserves a quick check as well, especially when the form contains CJK text, custom fonts, symbols, check boxes, or drop-down fields. A server may not have the same fonts as a developer workstation, and that difference can affect how field content appears after flattening.
Conclusion
For production systems, keep the editable source form separate from the generated read-only or flattened output. That small separation makes template updates, data corrections, and troubleshooting much easier than trying to recover structure from a file that has already been finalized.
Top comments (0)