COMING SOON: Spring 2026 Release Arrives April 15th

Home

All Blogs

How to Programmatically Fill, Flatten, and Export PDF Forms in .NET and Java

Published April 09, 2026

Updated April 09, 2026

Read time

5 min

email
linkedIn
twitter
link

How to Programmatically Fill, Flatten, and Export PDF Forms in .NET and Java

Sanity Image

Garry Klooesterman

Senior Technical Content Creator

Summary: Manually managing PDF forms at scale often leads to values that exist in the file but fail to appear in the viewer. This post explores how to programmatically bridge the gap between the logical Field layer and the visual Widget layer using the Apryse Server SDK. You'll learn why relying on the NeedAppearances flag is a risky shortcut, how to use XFDF for high-speed database-to-PDF workflows, and the steps to flatten and export professional-grade documents in C# and Java.

Sanity Image

Introduction

Copied to clipboard

Filling a PDF form should be as simple as setting a variable but in reality, developers often encounter users opening a generated PDF in a browser or mobile viewer, and the fields look completely blank until the user clicks on them. This happens because of a disconnect in the PDF's internal structure between the data and its visual representation. In enterprise environments where documents like W-9s, contracts, or permits must be legally binding and visually consistent, clicking to see data isn't an option.

To solve this, we need to do more than just basic form filling and understand how to incorporate data directly into the document's visual layer. Using the Apryse Server SDK, we can programmatically control this process. This blog will look at the difference between Fields and Widgets, show you how to leverage XFDF for bulk processing, and provide the C# and Java code needed to ensure your exported PDFs look exactly the same on a screen as they do on a printed page.

How Forms Actually Work (Fields vs. Widgets)

Copied to clipboard

Most people think a field is just a box on a page. In reality, a PDF splits these into two parts:

  • The Field: This is the logic layer. It holds the value (for example, "John Doe").
  • The Widget: This is the visual layer. It’s an annotation that dictates where on the page the text appears, what font is used, and its color.

The problem is that if you update the Field value but don't call RefreshAppearance(), the PDF might contain your data, but the Widget will keep showing its old, cached visual or nothing at all. Relying on the NeedAppearances flag is notoriously unreliable and causes "Save Changes" prompts to pop up for the user.

Working With FDF and XFDF

Copied to clipboard

If you're dealing with hundreds of records, you don't want to loop through fields manually. Instead, you can use XFDF. It’s essentially an XML representation of your form data.

You can extract data from a filled PDF into an XFDF string or take a string from your database and inject it into a blank template in one shot. It’s significantly faster for batch processing.

Here is the order of the process for what’s happening:

  1. Query your DB.
  2. Generate an XFDF string for the record.
  3. Merge the XFDF into your PDF template.
  4. Flatten and export the file.

When to use Forms vs. DocGen?

Copied to clipboard

It comes down to who owns the design:

  • Forms (AcroForms): When you are given a pre-existing PDF (like a W-9 or a permit) that already has defined boxes.
  • DocGen: When you are designing the document from scratch in Word or HTML and just want to flow data into a flexible layout.

How to Get Started

Copied to clipboard

Getting started on this project requires just a few steps before we can get into the main how to of the blog.

  1. First, follow the guides to set up the Apryse Server SDK for the C# or Java PDF Library, or both if you like.
  2. Next, get your Apryse trial key.

For the examples in this blog, I’ll be using C# and Java, but the code is available in other languages as well, like Python, C++, and JavaScript.

How to Fill Forms in C# and Java

Copied to clipboard

Now, let’s look at the code we’ll need for our project. The pattern is the same in both languages: load the doc, find the field by its "fully qualified name" (like employee.name.first), and update it.

C# Example

Copied to clipboard

That was the C# example. Now, let’s look at the Java version of the same code.

Java Example

Copied to clipboard

See our full Flatten, Create, Modify PDF Forms – Interactive Forms code sample for more details.

Breaking Down the Code

Copied to clipboard

Let’s take a look at the code above, section by section, and see what each part does.

I’m only reviewing the C# code, but the Java code follows the same logic.

Find the Field

Copied to clipboard

This is the critical part to finding the field we want to update and setting the value. Don’t forget to refresh the appearance of the field to show the value after we’ve set it.

Set Checkbox

Copied to clipboard

For checkboxes, we’re checking to see if the checkbox exists and if it does, we set the value to “check” the box.

Set Combo Box (Dropdown Menu)

Copied to clipboard

We check to see if the combo box exists and if it does, we set the value to “select” an item from the list.

Set Radio Button

Copied to clipboard

For radio buttons, we do basically the same thing as with the other 2 options: we check to see if it exists and then if it does, set the value to “select” the option we want.

Flatten the Document

Copied to clipboard

Now we want to flatten the document to make it permanent and secure so that it can’t be edited.

    // Flattening makes the data "permanent" and uneditable 
    doc.FlattenAnnotations(true);  

Save the Document

Copied to clipboard

And last, save the document.

    doc.Save("output.pdf", SDFDoc.SaveOptions.e_linearized); 

FAQ

Copied to clipboard

What if I have two fields with the same name?

In a PDF, if two fields share the same name, they share the same value. Updating one will update the other automatically. This is actually a great way to handle "Name" fields that appear on every page of a long contract.

How do I find all the field names in a mystery PDF?

Use a FieldIterator. You can loop through the document and print field.GetName() to see exactly what strings you need to target in your code.

Is there a way to make fields "Read Only" without flattening?

Yes. You can use field.SetFlag(Field.e_read_only, true). This keeps the "Form" structure intact but prevents the user from typing in the boxes.

Does this work for Digital Signatures?

Signatures are a special type of form field. You can create a SignatureWidget programmatically, but filling it usually involves a certificate-based signing process rather than a simple text value.

What is the "e_linearized" save option?

It's often called "Fast Web View." It optimizes the PDF so that the first page can be displayed in a browser while the rest of the file is still downloading in the background. Highly recommended for web apps.

Conclusion

Copied to clipboard

Successful server-side form filling is about ensuring document integrity across the entire digital lifecycle. By moving away from unreliable shortcuts like the NeedAppearances flag and manually refreshing your appearance streams, you eliminate the risk of empty fields and inconsistent rendering.

Whether you are populating a single application or batch-processing thousands of records using XFDF, the goal remains the same: a final, flattened document that serves as a tamper-proof and professional record.

The Apryse Server SDK simplifies this process into a few lines of code, allowing you to focus on your data.

Contact our sales team for any questions and support.

Suggested Reads

Copied to clipboard