PDFDriver Library

Flex is not that great when you want to print multiple pages combined content. Things like multiple datagrids intercalated with textfields for example. Add the requirement for a header and a footer and things start getting really complicated. Maybe you also need to have an identification element like a watermark on each page beneath the actual page content…

PDFDriver can handle all of the above. It makes use of two open source libraries (alivepdf and flexreport) and adds a little magic of its own.

Overview
PDFDriver “prints” a special canvas mxml component to a pdf file, splitting the mxml template into multiple pages based on the page size.
You can see an example here: PDFDriver Example. “Add random content” button will generate a random header, body and footer based on a basic lorem ipsum generator. “Export content to PDF” will trigger a PDF file download of the generated content split into pages.

Notes:

  • you need flash 10 to be able to download the generated pdf file
  • due to the way flash displays datagrids you will not see all datagrid columns after generating content but they will appear in the generated pdf file

How to call it.
1) Include PDFDriver.swc in your flex project library path.
2) Create a canvas mxml component containing the following structure:

<AbsoluteLayer>*</AbsoluteLayer>
<Fixedlayer>
<Header>*</Header>
<Body>*</Body>
<Footer>*</Footer>
</Fixedlayer>

AbsoluteLayer – layer appearing on each page as watermark, PDFDriver won’t split this one into multiple pages so make sure this content fits on one page.
FixedLayer – content from will be split into pages, and will appear on each page.
* – currently supported mxml components: HBox, VBox, Label, Text, PrintGrid (simillar to PrintDataGrid), Image, HRule. These tags will be encoded in the pdf file respecting their properties within the overall canvas mxml component: position, size, color, etc..
3) Make sure all elements within this canvas have been loaded
4) Generate the pdf file

import com.asabau.pdf_driver.PDFDriver;
private var pdfDriver:PDFDriver = new PDFDriver();
pdfSettings = {title: "PDF Title", author: "PDF Author", creator: "PDF Creator"}
pdfDriver.print(canvasInstance, pdfSettings, handlePDFContent);
private function handlePDFContent(exportByteArray:ByteArray = null):void {
fileReference = new FileReference();
fileReference.save(exportByteArray,"content.pdf");
}

PDFPrint.print function takes 3 arguments:

  • instance to print containing the AbsoluteLayer and FixedLayer
  • pdfSettings object containing title, author and creator fields
  • a callback function that will be called after the pdf content will be generated, it has a ByteArray argument – data that can be used to save the generated content as a file on the end user pc.

How it works
PDFDriver takes the mxml template content and splits it into 3 entities: header, body, footer. It determines the height of the body based on page height minus header and footer heights. It splits the body elements in multiple pages, keeping the datagrid headers from one page to another.  The basic logic behind splitting the body (same logic as in flexreport) is to remove all body elements and then add one at a time (in case of datagrids, one row is added at a time) and see if the content added has a height larger than the calculated body height. One easy way to check for this is to monitor whether or not body has scrollbars.  When moving to a new page, all current body elements are removed from the displayList and we start the process all over again with the remaining body elements.

For each document page, header and footer elements are all visible. For body just the elements from the current page are visible. For AbsoluteLayer all elements are visible. All these elements are parsed and inserted into a pdf page with the help of special functions built on top of alivepdf for each mxml type.

Links
FlexReport – pagination starting point was based on this project, ended up keeping less than 30% of the original pagination code
AlivePDF – used for generating the pdf files, extended the main PDF class to handle various mxml tags, original classes left unchanged
PDFDriver example – “view source” enabled
Sample generated PDF File
PDFDriver Library – source code released under Simplified BSD License

4 thoughts on “PDFDriver Library”

  1. Great Job!

    Just one question.. is it possible to generate the pdf without showing the template?
    Thank you in advance

    Mark

  2. Hi,
    Thanks for the wonderful codes.
    I need one more help on this. how can i set headertext for the columns ?

    Thanks in advance
    Anantha Prasad

  3. Hi Andrei,

    You have done great work and it will be very useful in my work. Just wanted to know if you can post the source files also. I have changed the AlivePDF source files and would to incoporate it into the PDFDriver library. Also any plans on upgrading this for Flex 4.

    Thanks in advance,
    Jim

Leave a Reply

Your email address will not be published. Required fields are marked *