Flatten PDF Form Fields with iTextSharp – Two Methods – ASP.NET

I will show two methods to flatten editable form fields in a PDF file. Method 1 is true form flattening and method 2 is just making the editable fields read only. Personally I was using method 1 for some time, however in some instances (more specifically when merging images into a PDF file and messing with the editable fields), this specific method would throw an error upon opening the PDF file in Adobe Reader stating that Acrobat may not display the page correctly, however I never noticed anything wrong with the PDF file, everything was being displayed correctly, but this “error” was kinda annoying, so I opted to change the code a bit to make all the fields Read Only instead of flattening the form.

Below is the code to perform both, flatten the form and make all the fields Read Only.

Method 1

Just create a stamper and set its FormFlattening to true.

C# Code

stamper.FormFlattening = True

VB.Net Code

stamper.FormFlattening = True

Method 2

Create a stamper, read all the AcroFields into an array and loop thru them setting them READ ONLY one by one.

C# Code

string[] fields = stamper.AcroFields.Fields.Select(x => x.Key).ToArray();
for (int key = 0; key <= fields.Count - 1; key++) {
	stamper.AcroFields.SetFieldProperty(fields(key), "setfflags", PdfFormField.FF_READ_ONLY, null);
}

VB.Net Code

Dim fields() As String = stamper.AcroFields.Fields.[Select](Function(x) x.Key).ToArray()
For key As Integer = 0 To fields.Count - 1
    stamper.AcroFields.SetFieldProperty(fields(key), "setfflags", PdfFormField.FF_READ_ONLY, Nothing)
Next

Complete Code

C# Code

private void flattenPdfFile(ref byte[] fileBytes)
{
	PdfReader reader = new PdfReader(fileBytes);
	MemoryStream ms = new MemoryStream();
	PdfStamper stamper = new PdfStamper(reader, ms, "4"); //Creating the PDF in version 1.4

	//Method 1
	stamper.FormFlattening = true;

	//Method 1
	string[] fields = stamper.AcroFields.Fields.Select(x => x.Key).ToArray();
	for (int key = 0; key <= fields.Count - 1; key++) {
		stamper.AcroFields.SetFieldProperty(fields(key), "setfflags", PdfFormField.FF_READ_ONLY, null);
	}

	stamper.Writer.CloseStream = false;
	stamper.Close();
	ms.Position = 0;
	fileBytes = ms.ToArray();

	ms.Flush();
	reader.Close();
}

VB.Net Code

Private Sub flattenPdfFile(ByRef fileBytes As Byte())
	Dim reader As PdfReader = New PdfReader(fileBytes)
	Dim ms As MemoryStream = New MemoryStream()
	Dim stamper As PdfStamper = New PdfStamper(reader, ms, "4") 'Creating the PDF in version 1.4
	
	'Method 1
	stamper.FormFlattening = True
	
	'Method 2
	Dim fields() As String = stamper.AcroFields.Fields.[Select](Function(x) x.Key).ToArray()
	For key As Integer = 0 To fields.Count - 1
		stamper.AcroFields.SetFieldProperty(fields(key), "setfflags", PdfFormField.FF_READ_ONLY, Nothing)
	Next

	stamper.Writer.CloseStream = False
	stamper.Close()
	ms.Position = 0
	fileBytes = ms.ToArray()

	ms.Flush()
	reader.Close()
End Sub



 

Esau Silva
Software Engineer at Region One ESC
Full Stack Software Engineer working with Microsoft technologies, ReactJS is awesome and avid Brazilian Jiu-Jitsu practitioner
Spread the love

5 thoughts on “Flatten PDF Form Fields with iTextSharp – Two Methods – ASP.NET

  1. Robert says:

    I’ve made a pdf in Livecycle Designer
    When i use your routine, this is nog working (not read only and not showing any data)
    Which version of iText are you using?

    • jgezau says:

      I’ve had bad experiences with PDF forms created with Livecycle Designer. One of those experiences was when I tried to edit a PDF Form with Acrobat DC, it was telling me that I couldn’t edit it using DC because it was created with Livecycle Designer. My guess is that Livecycle Designer creates forms that are internally different than forms created by Acrobat, so this might be the reason. And I’m using iText 5.2

  2. Geoff Hill says:

    C#
    for (int key = 0; key <= fields.Count – 1; key++) {
    stamper.AcroFields.SetFieldProperty(fields(key), "setfflags", PdfFormField.FF_READ_ONLY, null);
    }

    this is a mix of vb and c# it should read
    for (int key = 0; key < fields.length; key++) {
    stamper.AcroFields.SetFieldProperty(fields[key], "setfflags", PdfFormField.FF_READ_ONLY, null);

    Keep up the good work.
    Regards Geoff

  3. michael says:

    Any way to only print the field content of a PDF form? I need to programmatically fill out a PDF form then print to a pre-printed form. Sounds weird, but this is my task. My client has pre-printed forms that print in landscape orientation and must get data to print at the correct location. So I thought i’d fill out the form in code then just remove the bottom layer of the form leaving the top layer of the fields. Make sense? can do?

Leave a Reply

Your email address will not be published. Required fields are marked *