Awesome Code of the Week

So, "Awesome Code of the Week"? Yeah, I think you'll agree after this blog post. Let's just say if there was an award for this, I'd take the cake - AND the cake pan.

So what is it? Well, its simply generating PDF reports and emailing them. Woooaah, how cool is that? Not really on its own, however its very cool in the whole process that I'm doing to generate those PDF reports.

History
Our company, over the past several years, have been developing and perfecting a ASP based application for one of our clients. In it, we have built a custom reporting engine that takes XML spit out from SQL Server, translates it into managable XML via another XML translation process, then formats it using XSLT. This process, cool indeedy, was a beast to bring into the .NET world.

One report is generated all the time, printed / and or saved directly from the browser. A new request came across to take this report and have selection of multiple different parameters to generate X number of reports, and be delivered to the user. For instance, you select 3 items from Item A, 4 items from Item B. The user wants reports for all the combinations, so in this instance we have 12 reporrts that are generated. The current report, as-is, cannot handle this, and would take a lot to modify.

The Design
Back in June of this year, we decided that the users would come to a new ASP.NET application (under the realm of the ASP application), make their selections, and a PDF will be created while the users waited. As time went on, we realized that some of these combinations (upwards into the 100s) could take a long time to process.

As such, we had to come up with a new way of handling it. I realized at that point, that it may be best to spawn a new thread, let the user see that the request has been submitted, and then process the reports in the background. Ultimately, it would email the user the PDF report once finished. All was well, and a tremendous time was estimated.

The Coding
This week, I sat out to start this project, I didn't want it to become a daunting task, and then it hit me (or a lightbulb actually turned on in my head (which is very odd (and scary) since who wants a lightbulb in your head)). I realized that the easiest solution was to call the ASP report for each combination, creating the PDF on the fly.

So, there I sat, figuring out how to use WebRequest and WebResponse to POST and retrieve the HTML from the page. Success! I was able to post my different parameters in the format the underlying ASP page knew about, cool.

Next step, creating that pesky PDF file. I ran across several different PDF components, and WebSupergoo provided ABCPdf for .NET that would allow me to stick the HTML into a page, and continue on.

Last steps, zipping up the file and emailing. Now, here's where the tricky part came, not due to complexity of zipping the file, but due to how VB.NET handles declarazations of arrays. Boy, it was pain to figure out that in VB.NET, when you declare an array, you're actually setting the upper bounds of the array, not the size. After about 30 min, I finally figured that out (which is why I like C# so much), things started working again. I used #zipLib to do my zip compression, and all was well. The email got the attachment and was sent out...simple as pie.

Performance Testing
Now, this subject is super tricky in our development environment at work, due to the fact that our development server is a Pentium II 333Mhz with 256MB of RAM. Can you say screeching fast? Well, you couldn't on this machine (we really need new hardware). Anyway, as of the writing of this blog post, I started a combination that will generate roughly 6045 reports, which (if I did the math correct for our dev server with 30 reports for 15 min), its going to take about 50 hours to complete. Wow, is right...do I need to say that we need newer hardware?

The Cool Factor
So, what's cool about this? Well, I'm using an ASP.NET application that spawns a thread to POST a webpage to an ASP application, retrieve its HTML, stick it in a PDF, zip that PDF up, and email it to the user. How fricking cool is that.

5 Comments

  • with the exception of the pdf lib you used, I've done this very same thing... a long long time ago.



    Of course I cant say I've got any webcontrols that come close to the quality stuff you write.

  • Sounds like a major perf problem. I'd recommend having a seperate box on production Queue report requests and process them, rather than take up resources on your web box. Make the solution even more elaborate by using a Web Service to kick off the ASP/HTML/PDF/Email job :)

  • Well, remember Ron, its only our dev box thats the problem, the production server is a Dual Xeon processor machine w/ 2GB of RAM. The reports don't take nearly any time to run on that bad boy :) However, additional hardware isn't possible since they cannot afford it, etc. Politics. Its not like its a high-demand report that will be run all day long by 500+ users...In most cases, the # of reports that will be generated will be in the 10s.

  • It's not just cool, it's kewl! With the capital O:)

  • Interesting, Matt. Worked on something like that a year ago. It sounds like we had a bit more budget. We ended up with an Async PDF WebService with a custom SQL Server based queue. The service "called back" to the website with a success or failure url to update the system with the pdf generation status. It's still humming along.



    It'll be nice when SQL Reporting Services is solid enough that this is a no brainer.

Comments have been disabled for this content.