Printing in Bulk with Flex

This casestudy demonstrates how to use PrintAdvancedDataGrid and a custom itemRenderer to print multiple pages of data and graphics, using the SWFloader component.


Final Result Preview

Let's take a look at the final result we will be working towards - below is an overview of a 12 page PDF printed from a Flex application using the techniques in this article:

flex_print_preview

Demonstrated in This Tutorial:

  1. Using FlexPrintJob class.
  2. Using PrintAdvancedDataGrid.
  3. Creating a custom itemRenderer with a SWFLoader.
  4. Printing a header and footer.
  5. Filtering a collectionView.
  6. Printing a DataGrid with height that exceeds 7500.

Some Difficulties With Regards to Flex Printing:

  1. Your content or DataGrid rows must all be visible on the stage or they won't print.
  2. Adding manual page breaks is difficult, and achieved through setting your rowHeight to match what you want displayed on each printed page.
  3. Flex printing goes haywire if your total PrintAdvancedDataGrid content height is greater than approximately 7500 pixels, necesitating a workaround of multiple PrintAdvancedDataGrids.

Step 1: Import the Printing Classes

Begin by importing the necessary print classes, as well as your print renderer into your Flex project:


Step 2: Create a View for PrintAdvancedDataGrid and itemRenderer

Create a view State for your bulk printing. In my case, I created a state called printState.

*alternatively, you can create an instance of your PrintAdvancedDataGrid and itemRenderer and add them to the stage via actionscript, but for a bulk printing project I found this to be too difficult to work with, and as I was trying to print SWFs that are XML driven, I needed to make sure that my SWFs were displaying correctly before printing.


Step 3: Add Your PrintAdvancedDataGrid

If you need a total printing area greater than 7500 in height, you'll need another PrintAdvancedDataGrid for each area


Step 4: Set Your PrintAdvancedDataGrid options

One thing I found important was to set the option

According to the PrintDataGrid Control page from the Adobe Flex 3 LiveDocs, the sizeToPage property makes sure that the PrintAdvancedDataGrid control removes any partially visible or empty rows and to resize itself to include only complete rows in the current view.


Step 5: Add Your itemRenderer

Add an itemRenderer to your AdvancedDataGridColumn.


Step 6: Create the itemRenderer Component

In my case, I wanted to accomplish several things with the itemRenderer:

  1. add a SWFLoader
  2. add a header with the page title
  3. add a side footer with my url
  4. add spacing to the top, bottom and sides for proper printing

Since my URL worked better as vertical text, I found it much better to use a SWF for this text instead of a text box. You can be creative with your itemRenderer, adding data items from your XML or datasource as well as logos, URLs, etc. Here are the display items from inside my code for the itemRenderer component, which is also found in the src/com/reiman/PrintItemRenderer.mxml file in the download package for this tutorial:


Step 7: Add the Basic Actionscript FlexPrintJob Code to Your main.mxml File


Step 8: Set printJob Scale Type

Choose the printJob scale type you want to use (to read about FlexPrintJob scale types, check the Flex LiveDocs page here), and optionally set the printasBitmap option. I wanted my items to print as vector, and in fact this setting was key to my content printing correctly.


Step 9: Add Code to Execute Before the printJob

Add any alerts or actions you want to perform upon printing (such as an Alert to tell the user to turn on LANDSCAPE printing). For Example:

If you want to set an Alert, it must execute before your printing begins. Please look at the code provided in the download assocated with this tutorial for the printAlert() in the main.mxml file.


Step 10: Set Your Printing width and height Variables

Set your before printing width and height values for the PrintAdvancedDataGridwidth, and rowHeight


Step 11: Set the New Values

Set the new values for the height, width, and rowHeight to equal the FlexPrintJob values


Step 12: Add Multiple Pages Code to FlexPrintJob

Add your code to accomodate adding multiple pages to the printJob. According to the Flex LiveDocs, this nextPage() check is supposed to ensure that your content will print correctly regardless of your AdvancedDataGrid height, although I found that after a height of approximately 7500, the printing fails to complete correctly.


Step 13: Optional Adjust the printGrid Height

I found that I got fewer printing errors when I added this to the code from Step 12:

So now my total code for Step 12 looks like this:

This seems to have to do with Flex 3's problem or bug regarding printing datagrids with a large height, which is a real problem for printing things like multiple SWFs or images, because your datagrid height must in fact reflect the total height of the images or SWFs being printed!


Step 14: Add the Code to add Anything Else to Your printJob


Step 15: Send Your printJob

Close your printJob, and perform any additional functions such as an Alert, and resetting the printGrid and printColumn values back to what they were before printing. If you are using a view State for printing, where the user has perhaps a Print Center type interface where they can see what they are about to print, this would be useful. If you choose to add the PrintAdvancedDataGrid to the stage via actionscript, then this would be unnecessary, and in this step you would instead remove the PrintAdvancedDataGrid from the stage.


Step 16: Add Another PrintAdvancedDataGrid if Your Content Exceeds 7500 Height


Step 17: Duplicate Your dataProvider and resultHandler

My data call looked like this originally:

All I needed to do was add an additional result handler, so that the data for the second PrintAdvancedDatagrid would be separate:

Then I added a new result handler:

This new dataProvider for the second PrintAdvancedDatagrid is set in my stripQuiz2() filter function.


Step 18: Add collectionView Variables and Additional dataProvider

In my case, I needed to add 3 new ListCollectionViews, and 1 more dataProvider:


Step 19: Add filterFunction Functions

For the two datagrids I wished to print from, I needed filters that would perform the following functions:

  1. Strip out certain activity types from my printing list, as some were not necessary
  2. Truncate the data at 12 entries, as after extensive testing I found that this was the limit for successfully printing full page SWFs from the datagrid
  3. Remove the first 12 entries from the ListCollectionView for the 2nd PrintAdvancedDatagrid

This resulted in the creation of the following functions:


Step 20: Add Second printGrid to printJob

Before sending the printJob, I added the second PrintAdvancedDatagrid to be printed:

For a better look at the complete code, please download the source files associated with this tutorial and take a look at the main.mxml file.


Conclusion

This might not be the most elegant solution to bulk printing SWFs from Flex, but it is a solution that I found works reliably, with high quality output. Printing in Flex can be a real bear, but that doesn't mean you should overlook the options that are available to you, in particular through the use of PrintDatagrid and PrintAdvancedDatagrid. Thanks very much for reading my tutorial, and I look forward to any questions and comments you may have.

Tags:

Comments

Related Articles