iTextSharp Form Filling PDF

Though PDF, in my opinion, is often just a plug for the deficiencis of HTML/CSS and the browsers, because printing was never really thought into the web-equation, it does at least do the job.

So to get the job done, iTextSharp is a really great tool for your everyday .Net PDF needs, and will do a lot of the things you have to pay multi-bucks for in commercial products.

I recently came across a project where form-filling a PDF form from ASP.Net seemed a viable alternativ to the always difficult task of programming PDF from the bottom. The documentation for iTextSharp was never all that hot, and for form filling it is decidedly cold, so I knew I’d probably have to discover a trick or two myself…

The first thing I found out is that apparently only PDF-forms produced by Acrobat 5 can be filled. On the downside, this is a fairly old Acrobat version but I save a lot of old software in my museum and just installed it in a VMWare machine. On the upside it also turned out that Acrobat 7 forms take up about 20 times as much space as Acrobat 5, at least for my form! This translates directly into client load time, so it didn’t worry me one bit.

The second thing was harder to track down. My prototype worked perfectly, saving directly to a filestream. But when I put it into the ASP.Net application, and wanted output in a memorystream instead, I ran into trouble as iTextSharp would close the stream before I had a chance to send it to the browser. Luckily Tim Wirtz had asked for support on the same problem on SourceForge (his mail is here) and had an answer by Paulo Soares, the father of iTextSharp. The answer didn’t solve the problem, and I was really tired of open-source, until I realized that having the source I could actually debug it – and heureka, there was the solution. It is here:

                                 PdfReader reader = new PdfReader(formFile);
                                 MemoryStream stream = new MemoryStream();
                                 PdfStamper stamp = new PdfStamper(reader,stream);
                                 AcroFields fields = stamp.AcroFields;
                                 // set form fields
                                 fields.SetField("SNavn", am.Saelger.Navn);
                                 fields.SetField("KNavn", am.Koeber.Navn);
                                 // flatten form fields and close document
                                 stamp.FormFlattening = true;
                                 // very important to keep the MemoryStream intact
stamp.Writer.CloseStream = false;

So thanks to both Tim and Paulo – without that posting, I’d probably have given up.

Posted in C#

2 thoughts on “iTextSharp Form Filling PDF

  1. Michael Christensen

    As MemoryStream derives from Stream, which implements IDisposable, one should in principle enclose the memorystream in a using-statement (scoped around the streaming to the client), to ensure proper cleanup.

    You have to wonder if this really has any effect on a MemoryStream though, since it would not appear to hold handles to any unmanaged ressources – it certainly seems to be a do-nothing, inherited requirement judging from the Mono, SSCLI/Rotor and Portable.NET implementations of MemoryStream and Stream.

    Their implementations of Stream.Dispose() just calls Close(), which does no cleanup in either version. This is easy to understand, since ordinary managed memory allocation should be cleaned up without problems by the garbage collector).

    Of course, the “real” .NET implementation could be quite different…

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s