PDF-Reuse + Reduce & Recycle
One thing Santa should be glad about is that he doesn't have to deal with billing. Can you imagine having to invoice all the parents of the world? Sadly in the commercial sector we have to worry about sending invoice to clients. And as an overhead - you can't invoice for invoicing after all - we want to automate it all away. What better language to use than Perl?
While invoices these days don't actually have to be printed on paper anymore, they remain simulated paper documents: It's time to get Perl to create a bunch of PDFs for us.
We're building a billing solution for Advertising Agency. It has the usual Estimate → Purchase Order → Invoice cycle, with Detail, Rate, Qty and Amount format. Just to make this more complicated it has varied column information for handling Print Media & Audio/Video Media with more detail on print media position & A/V media program slot and timing. In some cases, each media type will be handled by different legal entities for manage tax related issues. Finally, the requirements were:
- 6 work segments (Production, Production with PO, Print Media, Audio/Video, Production with TAX)
- Upto 6 different legal entities for each segment
- 3 type of estimates
- Purchase Order
- 3 type of Release Orders for handle media communication
- 3 type of invoices
Wow! That's a lot of stuff to consider.
We went in search of suitable PDF production module. We mainly looked for:
- Ability to tailor build the document
- A module that gives production control in pixel level
- Flexible options to set page properties
- Option to implement signatures
- Position control to handle page continuation
After a lengthy search for few days, we finally zeroed in PDF::Reuse. It did not have user friendly function wraps for graphical output, but it offered a developer friendly core functions to control the graphical output in a pixel level. It helped to wrap our custom functions to handle in generic way.
Map to Reuse, Reduce & Recycle
One of PDF::Reuse's main advantage is that it can take an existing PDF - something that our designers can create with their standard PDF tools - and then all we have to do is add the various per invoice details to it.
The code to re-use a PDF with PDF::Reuse is really simple:
The feature of reusing the existing PDF and writing content over that, helped to reuse the existing legal entity letter pads in specific company document production. It's avoided manual graphic production work.
A Range of Functions
The PDF::Reuse module provides a bunch of primative functions for adding data to our document. For example, we've already seen using the
prText() function to add text to the document. But PDF::Reuse provides a plethora of other functions that can do all kinds of things.
These can be as simple as
Or as powerful as
The problem with these functions is that they're all primative. If we want to create our document in a sensbile fashion we need to build up our own libray on top of these simplistic functions.
We classified the document we wanted to write into three major parts:
- The page layout and page background
It looks like a core wrapper function we need is some way to write out a row of row structure to meet individual lines and table like outputs. The wrapper function constructed based on
It will produce a title Production Estimate in page center. A data structure that produces several rows look like this:
Writing the code to make this work is actually quite fiddly: We have to do a lot of accounting of how much space each column takes up, and keep track of where we need to place the next line.
Rather than showing you pages and pages of our code, here's an example of a small snippet of code that we use to create the header and shows some of these challenges:
You can see the techniques that we leverage: Keeping track of the changes
$y as we render each section, rendering column by column and looking up the corresponding header information for each data section, and using per page defaults when the meta data doesn't have settings in each section.
By abstracting this logic into sections we can deal with the complexity and build up a powerful library to easily create our own pages, making PDF::Reuse very powerful.
With our library of functions the creator will produce the PDF document based on given data on page properties & page content. In implementation case different structures are predefined first. During runtime, the bill information dynamically added to the structure. A basic structure created first, then it cloned and blended to different account needs.
PDF:Reuse core functions
PrImage itself helped to produce business quality documents with scalability and reusability. The modules simple and straight core functions helped us to achieve our custom document generation with ease and control. Even though we've been using it for six year, its continuously satisfying the evolving needs with the basic functions.
Now the documents become a part of our clients business communication also it gave us a business. Thanks PDF::Reuse.