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 intactstamp.Writer.CloseStream = false;stamp.Close();
So thanks to both Tim and Paulo – without that posting, I’d probably have given up.