Home > Actionscript/AS3, Flash > Flash AS3 PrintJob: Problems printing from Flash

Flash AS3 PrintJob: Problems printing from Flash

October 12th, 2009

Flash has a feature called PrintJob that allows you to print MovieClips – either by creating PDFs or simply sending them directly to a printer. Unfortunately, PrintJob has a poorly documented bug that can cause a lot of headaches. Sometimes, it will print blank pages. Other times, it will scale the pages incorrectly. The behavior is seemingly random and it is different on different computers. I had a lot of trouble printing from Flash with a recent project at work, but there is a remarkably simple solution. Read on…

In my project, I allowed a user to save PDFs to a print queue for printing at a later time. This was done by simply pushing the MovieClips onto an array. When a user hit the print button, I created a PrintJob and then looped through the array of MovieClips, scaling each one as needed to fill the page and then sending them to the printer. The actionscript code looked like this:

//-prints all saved pdfs:
public function printAllPages():void {
	if (savedPdfsArray.length > 0) { //if there are pdfs to print...
		var pj:PrintJob = new PrintJob(); //create printjob
		if(pj.start()) {
			for (var i:int=0; i < savedPdfsArray.length; i++) {            
				//scale it to fill the page (portrait orientation):
				var myScale:Number;
				myScale = Math.min(pj.pageWidth/savedPdfsArray[i].width, pj.pageHeight/savedPdfsArray[i].height);
				savedPdfsArray[i].scaleX = savedPdfsArray[i].scaleY = myScale;
				var printArea:Rectangle = new Rectangle(0, 0, pj.pageWidth/myScale, pj.pageHeight/myScale);

				pj.addPage(savedPdfsArray[i], printArea); //add page to print job
			}
			pj.send(); //send to printer
		}
		pj = null;
	}
	else { //if there are no pdfs in the queue...
		errorPopup.openMe("You do not have any pdfs saved in your queue.");
	}
}

This code worked perfectly on my PC, but occasionally gave me problems on an old iMac in the office. I had someone else test it on a newer Mac and it seemed fine, so I wrote it off as an outdated printer driver.

Then, when we sent it to the client, there were all sorts of problems. On some computers, it printed blank pages. On others, it scaled the pages incorrectly, so that the MovieClips didn't fill the page. It happened on both Macs and PCs. After a lot of Googling around without much success, I found this thread on Kirupa forum. One of the responders suggested that the MovieClips must be added to the stage or they won't print. I gave this a try and IT WORKED! It fixed all of the weird, unpredictable PrintJob behavior in my application. I quickly updated my code and the client was happy:

//-prints all saved pdfs:
public function printAllPages():void {
	if (savedPdfsArray.length > 0) { //if there are pdfs to print...
		var pj:PrintJob = new PrintJob(); //create printjob
		if(pj.start()) {
			for (var i:int=0; i < savedPdfsArray.length; i++) {
            
            			//========== printjob bug fix - prevent blank pages: ==========
                		savedPdfsArray[i].x = 2000; //keep it hidden to the side of the stage
                		stage.addChild(savedPdfsArray[i]); //add to stage - prevents blank pages
                		//=============================================================
                
				//scale it to fill the page (portrait orientation):
				var myScale:Number;
				myScale = Math.min(pj.pageWidth/savedPdfsArray[i].width, pj.pageHeight/savedPdfsArray[i].height);
				savedPdfsArray[i].scaleX = savedPdfsArray[i].scaleY = myScale;
				var printArea:Rectangle = new Rectangle(0, 0, pj.pageWidth/myScale, pj.pageHeight/myScale);

				pj.addPage(savedPdfsArray[i], printArea); //add page to print job
			}
			pj.send(); //send to printer
		}
        
        	//========== printjob bug fix - prevent blank pages: ==========
        	for (var j:int=0; j < savedPdfsArray.length; j++) {
        	    stage.removeChild(savedPdfsArray[j]); //don't forget to remove them from the stage
        	}
        	//=============================================================
        
		pj = null;
	}
	else { //if there are no pdfs in the queue...
		errorPopup.openMe("You do not have any pdfs saved in your queue.");
	}
}

I hope this post saves someone else a lot of hair-pulling. Thank you "orangehaze" and Kirupa forum!

Be Sociable, Share!

  1. david doull
    October 25th, 2009 at 23:25 | #1

    thanks – it helped me

  2. November 4th, 2009 at 06:46 | #2

    Thanks. it works for me also.

  3. November 23rd, 2009 at 21:09 | #3

    Thanks I will give her a try! And another thing to note – sometimes you’ll get errors like filters will not render at that size or 3d will not render. Even though you arent using them!

  4. admin
    November 25th, 2009 at 07:49 | #4

    @Elliot Geno
    Filtering large movieclips is always an issue in Flash. I created a workaround for the filtering problem on a project a few months ago that I have been meaning to post, so maybe I’ll do that next. Thanks.

  5. Adam Chromicz
    May 13th, 2010 at 19:03 | #5

    Awesome, Thanks so much, just add it to the stage, move it out of the way using an exagerated x or y value and bam, clients happy!!!!

  6. Hugo
    June 8th, 2010 at 00:34 | #6

    I have clients with a different problem printing from flash on Macs.
    It prints, but the fonts are all HUGE!!!
    It seems to only happen with text generated on dynamic text boxes…
    any ideas?

  7. admin
    June 8th, 2010 at 07:09 | #7

    @Hugo
    I haven’t seen that problem before. Are you creating the dynamic text with actionscript or is the textbox already on the stage? Here are a few things to try:
    – Make sure your fonts are embedded. Otherwise, it may be trying to substitute a font.
    – Are you scaling the Movieclip before printing? Maybe your font isn’t scaling for some reason.
    – Add the movieclips to the stage where you can view them to see if the fonts look correct on stage (or not).
    – Try a different font (embedding it of course)
    – Check the version of Flash you are using. I prefer working in Flash 9 (CS3) most of the time, but it had a few weird bugs that seem to be fixed in Flash 10.
    – Another trick I have for printing from Flash is to use the Bitmap.draw() method to essentially create a screenshot of a movieclip and then print that bitmap. Flash sometimes has problems with transparent PNGs and masks, but using the screenshot method fixes them.

    I hope that helps. If you leave a comment when you find the solution to your problem, it may help save other people some frustration.
    Andy

  8. Vladox
    September 22nd, 2010 at 11:30 | #8

    Hi
    I was trying to print the Stage and stumbled with a lot of problems getting the stage to resize properly so I use a combination of solutions, that involved converting the stage to a bitmap.

    Here my source:

    function PrintStage(evt:MouseEvent) {
    var printJob:PrintJob = new PrintJob();
    var options:PrintJobOptions = new PrintJobOptions();
    options.printAsBitmap = true;
    trace(“print called!”);
    if (printJob.start()) {
    var printSprite = new Sprite();

    var bitmapData:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight);
    bitmapData.draw(stage);
    var screenShot:Bitmap = new Bitmap(bitmapData);

    printSprite.addChild(screenShot);

    //========== printjob bug fix – prevent blank pages: ==========
    printSprite.x = 2000; //keep it hidden to the side of the stage
    stage.addChild(printSprite); //add to stage – prevents blank pages
    //=============================================================

    trace(“before printSprite width: ” + printSprite.width + ” printJob.pageWidth: ” + printJob.pageWidth);

    //scale it to fill the page (portrait orientation):
    var myScale:Number;
    myScale = Math.min(printJob.pageWidth/printSprite.width, printJob.pageHeight/printSprite.height);
    printSprite.scaleX = printSprite.scaleY = myScale;
    var printArea:Rectangle = new Rectangle(0, 0, printJob.pageWidth/myScale, printJob.pageHeight/myScale);

    trace(“after printSprite width: ” + printSprite.width + ” printJob.pageWidth: ” + printJob.pageWidth);

    printJob.addPage(printSprite,printArea,options);
    printJob.send();

    stage.removeChild(printSprite);
    printSprite = null;
    }
    }

    Hope it helps someone….

  9. admin
    September 23rd, 2010 at 07:00 | #9

    @Vladox
    Thanks for the solution! That reminds me that there is another “bug” in Printjob: if you have several PNGs or masked items on top of each other, they don’t always print correctly. The solution is similar to what you did here – create a Bitmap and do a Bitmap.draw() of your MovieClip, then print the Bitmap (after adding it to the stage of course).

    Thanks for posting your solution here!
    -Andy

  10. October 14th, 2010 at 03:35 | #10

    Thanks a lot! I was having this problem with blank space and adding item on stage fixed the problem!

    Actually the problem was that when I had a mask applied to one of the printable sprites, it is then that a blank area was being shown.

    Adding it to stage fixed the problem with the mask applied!

    Thanks a lot! :)

  11. Steve
    November 1st, 2010 at 19:52 | #11

    Wow, sometimes you find a snippit that saves your entire day.

  12. Tom
    April 21st, 2011 at 13:03 | #12

    Vladox,
    Your example is exactly what I was looking for. Thanks a thousand times over.

  13. September 6th, 2011 at 02:36 | #13

    Thanx for this. It is very useful!

  14. Anicham
    October 20th, 2011 at 04:14 | #14

    Hi,

    your example is very helpful for us. Actually you are using flash rite.
    Shall i try the same functionality in flex – Air application.if we can means . could you please tell me , how can i proceed to get the exact result as yours..

    waiting for ur reply.. its my urgent requirement….

  15. admin
    October 24th, 2011 at 10:42 | #15

    I don’t use Air or Flex much, but the code should be the same, since they all use AS3.

  16. Patricio
    April 5th, 2012 at 10:52 | #16

    Hi andy! Thanks for this article, it was helpful!

    Can I make you a question? How did you manage to print the PDFs? I’ve searched *a lot* for that but didn’t find anything useful, so I ended up generating the document itself in flash.

    Thank you!

    Patricio

  17. admin
    April 5th, 2012 at 15:29 | #17

    Ahh… The Print to PDF feature on this project was handled externally – using a plugin from Adobe that gives you a printer option of “PDF” when you print anything. Since this particular application was used by a limited group of salespeople, we were able to specify that they had to have the Print to PDF plugin installed on their computers.

    If I had to create PDFs for a publicly available application, I would probably send the info to a php script that would generate the PDF. There are several good PHP libraries that can do this.

  18. Patricio
    April 5th, 2012 at 18:42 | #18

    Thank you very much for your answer! I misunderstood you, and thought that you where printing server-generated PDFs from flash into paper, which seems not to be feasible with current AS3 PDF libs.

    Thanks again for answering =)

    Paricio

  19. April 23rd, 2012 at 21:26 | #19

    What’s the meaning of variable:savedPdfsArray? Is it the paths of Pdf files? I do not known how to use it.Please clarify.

  20. admin
    April 24th, 2012 at 19:50 | #20

    savedPdfsArray is just an array of movieclips that I print. In this application, a user can save multiple PDFs to a “print queue” (the savedPdfsArray) and then print them all at once.

  21. April 25th, 2012 at 19:35 | #21

    @admin
    Thanks for your help. Another question: Can AS3 convert pdf files to movieclips objects? I have no idea about it. Any suggestion or comments are welcomed.

  22. Michael
    September 5th, 2012 at 10:35 | #22

    admin,

    I have the same question as bencenche. I understand that you creating a queue of movieclips, which “contain” PDFs. Can you help with understanding how you loaded the PDFs into the movieclips?

    Thanks you

  23. admin
    September 5th, 2012 at 12:12 | #23

    Michael,
    Flash does not load or display PDFs. What I’m doing is creating MovieClips that look like PDFs, then sending them to a user’s printer. If you have ever downloaded Adobe Acrobat, it probably installed “Adobe PDF” as a printer on your machine. So, when Flash sends the MovieClips to your printer, you can save them as PDFs instead of printing them. Flash is not loading, displaying, creating, saving or printing a PDF. It is simply printing a MovieClip. Your computer has to do the PDF printing.

    If this solution isn’t workable, you could probably create an image and send it to a PHP script to generate the PDF. There are several PHP libraries that can generate PDFs dynamically.

  24. Thomas
    November 25th, 2014 at 02:14 | #24

    Thank you for this! I was having problem with the flash not publishing when scaling a sprite before printing it. Adding said Sprite to stage solved the problems :)

  1. October 26th, 2009 at 03:19 | #1

Top