Wow! I really need to get better at updating my blog with interesting little articles about this and that. Here's one example that I've been working with over the past two weeks.
A short background
The company I work for, Infopaq International, is a media watch company and delivers news clippings to customers in one of several formats. One possibility is (in the countries that allow this because of copyright legislation) to provide E-clippings in a PDF file.
Until now, this PDF file has been really simple with nothing but our logo at the top and the clipping centered on the page. I was asked to look into how we could beautify these e-clippings so they would be more aesthetically pleasing and also contain more information. For example, information about the customer, the media from which the clip came, etc. My colleague in Stockholm sent me a mock-up of how he would like the final PDF to look, and I set about figuring out how to get the job done.
The old solution was built using iTextSharp so i decided to have a closer look at what functionality was available in this library. I set off to try to programmatically build a PDF file the way my Swedish colleague wanted but soon discovered that this really wasn't as easy as I first had hoped. At least I found it to be quite challenging to get things to align just the way I wanted them to.
So I put my thinking cap back on and started to ponder what else could be done. After a bit of reading, a bit of Googleing and a lot of staring at iTextSharp, I decided to go for a different approach. I installed Adobe Acrobat and set off to design my PDF using a real PDF authoring utility. I thought (wrongly, by the way) that I could simply define some fixed strings in the template which I then could search-and-replace with data from my database. It turned out that PDF just doesn't support that possibility. But then it struck me. I remembered reading somewhere about filling out PDF forms from iTextSharp. I Googled a bit and decided to give it a try.
I designed a PDF form using Adobe LiveCycle Designer and assigned meaningful names to all the fields (there are about 30 fields in total on the form). Now it was only a question of using iTextSharp to fill out the fields and then spit out the finished result to the client. And now for some code:
// Open the template PDF file
PdfReader rdr = new PdfReader(HttpContext.Current.Server.MapPath("~/App_Data/Template.pdf"));
// _outStream is a HTTP Response Stream
PdfStamper stamper = new PdfStamper(rdr, _outStream);
// Grab our fields
AcroFields fields = stamper.AcroFields;
// And then a whole load of these (in this case reading the department name from XML):
// Close our stamper
stamper.FormFlattening = true;
stamper.FreeTextFlattening = true;
And that's just about all there is to it :)