- Home>
- .NET core>
- Fill out a PDF form using iTextSharp for .NET core.
iTextSharp is a popular library for working with PDF files. The unofficial port of the v4.16 is available for .NET core. In this post, I show examples of using the library to programmatically read and fill out a PDF form.
For this post, I am using a simple PDF form consisting of the following fields: “First Name”, “Last Name”, and a checkbox. By the way, if you haven’t created a PDF form before, one way to create a form is to use Microsoft Word to design the layout, save the file as a PDF and use Adobe Reader Pro to detect/add the fields.
In your .NET core or ASP.NET core application, add the iiTextSharp.LGPLv2.Core nuget package.
Per the documentation,
iTextSharp.LGPLv2.Core is an unofficial port of the latest LGPL version of the iTextSharp (V4.1.6) to .NET Core.
It is straightforward to get the fields using iTextSharp.
public ICollection GetFormFields(Stream pdfStream) { PdfReader reader = null; try { PdfReader pdfReader = new PdfReader(pdfStream); AcroFields acroFields = pdfReader.AcroFields; return acroFields.Fields.Keys; } finally { reader?.Close(); } }
The above method reads the PDF content as a stream and return all the fields’ names.
Below is the test and the output of running the method with our simple PDF form.
Test:
/// <summary> /// Test retrieving field names of a PDF form. /// @<see cref="IPDFFormService{T}.GetFormFields(System.IO.Stream)"/> /// </summary> [Fact] public void GetFieldNames() { Stream pdfStream = new FileStream(path:SamplePDFFilePath, mode:FileMode.Open); ICollection fieldNames = samplePDFFormService.GetFormFields(pdfStream); foreach (var fieldName in fieldNames) { _output.WriteLine(fieldName.ToString()); } pdfStream.Close(); }
Output:
Running PDFFormFillingExample.PDFFormFillingExampleTests.PDFFormFillingExampleTests.Services.SamplePDFFormServiceTests.GetFieldNames ... First Name Awesome Checkbox Last Name
Below show the sample codes to fill out the sample PDF.
public Stream FillForm(Stream inputStream, PDFSampleForm model) { Stream outStream = new MemoryStream(); PdfReader pdfReader = null; PdfStamper pdfStamper = null; Stream inStream = null; try { pdfReader = new PdfReader(inputStream); pdfStamper = new PdfStamper(pdfReader, outStream); AcroFields form = pdfStamper.AcroFields; form.SetField(SampleFormFieldNames.FirstName, model.FirstName); form.SetField(SampleFormFieldNames.LastName, model.LastName); form.SetField(SampleFormFieldNames.IAmAwesomeCheck, model.AwesomeCheck ? "Yes" : "Off"); // set this if you want the result PDF to not be editable. pdfStamper.FormFlattening = true; return outStream; } finally { pdfStamper?.Close(); pdfReader?.Close(); inStream?.Close(); } }
The test below demonstrates calling the method to fill out the form and output the result to the file.
/// <summary> /// Test setting values for the fields in a PDF. /// @<see cref="IPDFFormService{T}.FillForm(System.IO.Stream, T)"/> /// </summary> [Fact] public void FillForm() { PDFSampleForm sampleFormModel = new PDFSampleForm() { FirstName = "John", LastName = "Doe", AwesomeCheck = true }; using (Stream pdfInputStream = new FileStream(path: "SamplePDFForm.pdf", mode: FileMode.Open)) using(Stream resultPDFOutputStream = new FileStream(path: "SamplePDFFormFilled.pdf", mode: FileMode.Create)) using(Stream resultPDFStream = _samplePDFFormService.FillForm(pdfInputStream, sampleFormModel)) { // set the position of the stream to 0 to avoid corrupted PDF. resultPDFStream.Position = 0; _output.WriteLine(resultPDFStream.Position.ToString()); resultPDFStream.CopyTo(resultPDFOutputStream); } }
Note:
It is necessary to set the position of the result PDF stream to 0 before consuming the stream (e.g. before outputting the stream to a file or returning the stream as a payload of a HTTP request). Otherwise, the result PDF is broken.
Here is the result PDF which the above test produces.
The full sample project is available on GitHub.
Dynamically adjust font size of text to fit into a PDF text field using iTextSharp.LGPLv2.Core.
Stamp a PDF using iTextSharp for .NET core
Web scraping in C# using HtmlAgilityPack
Building multitenant application – Part 2: Storing value into database session context from ASP.NET core web API
Common frameworks, libraries and design patterns I use
Build and deploy a WebJob alongside web app using azure pipelines
Authenticate against azure ad using certificate in a client credentials flow
Notes on The Clean Architecture