Multiple page printing from a HTML Adobe AIR Application
April 26th, 2008 by vssr, DryIcons Coder
It’s been almost two months since Adobe released its first official version of Adobe Integrated Runtime — AIR 1.0. AIR provides a pretty flexible way for development of desktop-like applications by the use of web technologies: HTML / JavaScript, and Flash / Flex. In other words AIR allows web programmers to develop desktop applications. I speak from my own experience when I say that web developers have a hard time developing desktop applications.
I’m not sure what is behind this mysterious fact, but it’s so hard for most of the web geeks to develop a desktop apps (and perhaps vice versa). However, AIR seems to be something that all of us were waiting for a long time. It’s still version numero uno, but it seems to be working quite well.
There are a lot of things to be done and we are positive that they gonna happen pretty soon, since the web development community became very fond of AIR. To leave a side the Flash developers who seem to adjust nicely in every OO environment, the even webbies can now go much deeper, and don’t have to change their means.
Recently, we’ve got a project to develop a desktop application for “electronic reports” generation. Electronic reports are text files that contain a report in a specific predefined format.
Anyway, the application had to allow the user to enter data, and once the user would finish he’d be able to save the file and print the report on a paper. You can use SQLite as a Database with your AIR application, manipulate it through your JavaScript code and that seemed like a perfect solution. This was a great opportunity to actually dive into the AIR world. Everything went smooth till the print part.
First of all, HTML AIR applications don’t support window.print() function. We’ve spent a lot of time looking for something on the net, someone that had similar experience and perhaps might found a solution. And we did find something (simulates window.print function) that simulates single page printing. However this is not what we needed since it is limited to a single page printing. Our reports were few pages long so we had to extend the solution, or come up with a different one. We did quite of experiments, and following is what came to as a possible solution.
AIR is based on Flash functionalities, and if you are developing HTML AIR application then the HTML is rendered through the WebKit open source web browser engine. Since the native window.print() functionality is not available, you’ll have to use flash.printing tools. You can access it in your HTML/JavaScript AIR application through window.runtime.flash.printing.*. Also, you must bear in mind that you are able to print any Sprite, but in our case that’s the window.htmlLoader. A great disadvantage is that you must explicitily state all the pages you want to print and define a rectangle area of the Sprite (htmlLoader). In other words you have to prepare and populate every single page that you want to print, and then send it to the printer by using addPage().
Here are the steps you must complete for a printing job:
- Create a printJob (new window.runtime.flash.printing.PrintJob;)
- Create/Define a print Sprite, in our case that’s the window.htmlLoader
- Create printing options (new window.runtime.flash.printing.PrintJobOptions;)
- Start the printJob (pjob.start())
- Go through the pages you want to print, prepare them and add them for printing (pjob.addPage())
- Send the print job to the printer (pjob.send())
Important note is that you must set printAsBitmap to true in the printing options, since that is the only way to get something printed. The htmlLoader (all of your HTML) is printed as Bitmap, and that is quite a limitation since you get a blury print. Since we had to make quite of preprint preparations we decided to actually open a new application window which would handle the printing and actually never show that window. Once the printing was finished we’d close the window. Here is the complete code for such a solution:
// You might find useful to pass some value, number of rows for instance
function multiplePagePrint(numRows)
{
// Create the Print Job
var pjob = new window.runtime.flash.printing.PrintJob;
var psprite = window.htmlLoader; // Define the Sprite
if ( pjob.start() ) // Start the Print Job
{
// Define the Print Job Options
var poptions = new window.runtime.flash.printing.PrintJobOptions;
poptions.printAsBitmap = true; // Must print it as Bitmap
//after you've start the print job
// you can get any print specifics (page size etc.)
var pageHeight = pjob.pageHeight;
var pageWidth = pjob.pageWidth;
var paperHeight = pjob.paperHeight;
var paperWidth = pjob.paperWidth;
// Calculate the number of pages
var pagesToPrint = /** Your logic here **/;
// Add your pages:
for(var i = 0; i < pagesToPrint; i++)
{
/** Your logic here for calculating RECT_HEIGHT **/
var rect = new air.Rectangle(0, RECT_HEIGHT, pageWidth, pageHeight);
try{
pjob.addPage(psprite, rect, poptions);
} catch(e) {
air.trace(e);
}
}
try
{
pjob.send();
return true;
}
catch (err)
{
air.trace(err);
return false;
}
}
else
{
air.trace("PrintJob couldn't start");
return false;
}
}
As I’ve mentioned above the print is done in a separate application window which you can open with air.NativeWindow(), and here you can call your function. It handles all of the print activities, it is never being activated, that is, it is invisible to the user all the time, it starts the print, adds pages and prints, and once the print is done it is being closed. This way the user gets the system print interactive window for selecting the printer, number of copies to be printed etc.
Since our reports were mostly text reports we can’t say that this solution is perfect. As a matter of fact it is not, and I’ll advise you not to use it if you have to print text. However, it demonstrates the possibility of a multiple page printing in a HTML AIR application. The print results we got when printing in a Flash AIR application were far more superior. Some flash development in the current version of AIR is definitely recommended, at least if you need to print some text. I hope in future we gonna get improvements in AIR when it comes to printing in HTML AIR applications, and at least get the native window.print() functionality.
I strongly advice you to go through the ActionScript 3.0 Language and Components Reference even if you are a stubborn HTML / JavaScript developer, since the only thing that can happen is an extra benefit for your development skills.






April 27th, 2008 at 11:04 pm
Hi,
Nice and useful article for HTML guys starting off with AIR.
I had tried multi-page printing without success by changing htmlLoader.scrollV before each addPage. Moving the print area rectangle along the Y direction is a brilliant idea.
The only limitation of this solution inherited from htmlLoader is that the maximum height of htmlLoader can only be 2880. If your content is more than that then even this brilliant solution will not work.
I’ll pass along your improvement suggestions to the AIR team here at Adobe.
Cheers,
Anirudh
April 28th, 2008 at 8:05 am
Thanks Anirudh!
I’ve just noticed the limitation with the htmlLoader’s height. Tried to print out a report longer than 4 pages (height greater than 2880) but it didn’t worked out. It prints out only 3 and a half pages. Here goes out another improvement to be done in the later versions of AIR.
Regards,
vssr
April 28th, 2008 at 8:13 am
I’m for sure hoping that the AIR and Flash Player engineering teams have printing as a complete priority. I’ve messed around with this a good bit and the results are NOT satisfactory.
Jeff
April 28th, 2008 at 8:20 am
I agree with you Jeff, and definitely hope the next version of AIR will bring printing we are used to since it is inevitable in most of the cases when it comes to desktop apps.
Regards!
May 19th, 2008 at 9:57 am
Honestly, this 1 page printing restriction is really tiresome. Not just in Adobe Air, but also in “normal” Flash.
The one displayed on this page is the best workaround i have seen so far though.
I hope Adobe gets their act together, and starts developing a more useful printjob routine.
May 19th, 2008 at 10:04 am
Hi Mike! We understand (y)our trouble air/flash is causing when it comes to printing. Even this solution is restricted to heights below 2880, as Anirudh Sasikumar stated above. I just hope this “print fix” we are all expecting will happen very soon.
cheers!
May 20th, 2008 at 10:06 pm
Hello Gents,
A couple of weeks ago Anirudh was good enough to send me a JavaScript solution for printing and I got it to work, but it doesn’t really give us what we need.
Has anyone had an assurance from Adobe that the next iteration of Flex/AIR will be able to print from the file system? Is there any indication to that effect? Maybe its just because of my searches, but this appears to be a major, major, major drawback in AIR. And it could be only one of two things: a business decision to lead printing to something else, or a major oversight.
I just want to know that AIR will be able to print documents in the way any other desktop app can print documents, even just point to a file and print it, or it’s time to consider giving in to Microsoft.
JerryG
May 20th, 2008 at 10:22 pm
Hi Jerry,
I’m not sure that there is a solid (or of any kind for that matter) assurance that the next version of AIR/Flex would handle the printing as would be expected. However, it’s pretty obvious that the community is getting kind of frustrated for this matter, and all the common logic suggests that the next version of AIR would handle printing properly. What’s the point of having such a powerful tool in your hands, and yet not be able to perform a proper printing, when probability to print something in a Desktop app is pretty high.
vssr
July 4th, 2008 at 12:17 am
hi jerry, please explain a little about javascript integration