Archive

Posts Tagged ‘PrintJob’

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!

Top