Can I print an HTMLLoader (pdf) in Adobe Air?

2019-02-16 00:25发布

问题:

I'm using AlivePDF to create a PDF file, then save it to the desktop. I can then use an HTMLLoader to display my lovely PDF file.

Now, the print button in Adobe Reader works fine. However, there will be young children using the app, so I'd like to have a big "Print" button right above it.

I figured I could just start up a print job and feed it my HTMLLoader. This won't work because the HTML loader rasterizes the content.

Any suggestions?

回答1:

One answer I have found in order to solve this problem is called Cross-scripting PDF content. The idea is that a PDF can have embedded JavaScript, which can be called from the JavaScript within the HTML page "housing" said PDF (object tag only, no embed).

This site was of particular help. I had to simplify the JavaScript from that page down quite a bit. I kept getting syntax errors.

I also need my program to generate the PDF and the HTML content. I cannot ship a single PDF with embedded JS and an HTML file pointing to it. They need to be dynamically generated by the user. Here is a basic rundown:

private function printText(text:String):void
{
 var p:PDF=new PDF(Orientation.PORTRAIT, Unit.MM, Size.LETTER);
 p.addPage();
 p.addText(text, 100, 100);
 p.addJavaScript(this.getJavascript());
 var f:FileStream=new FileStream();

 var html:File=File.desktopDirectory.resolvePath("exported.html");
 f.open(html, FileMode.WRITE);
 f.writeUTF(this.getHtml());
 f.close();

 var file:File=File.desktopDirectory.resolvePath("exported.pdf");
 f.open(file, FileMode.WRITE);
 var bytes:ByteArray=p.save(Method.LOCAL);
 f.writeBytes(bytes);
 f.close();

Now that we have our two files, HTML and PDF, we can view the PDF, and create a giant purple print button for our younger / sight-impared users.

 if (HTMLLoader.pdfCapability == HTMLPDFCapability.STATUS_OK)
 {
  var win:PrintTitleWindow;  //the window w/giant button
  var htmlLoader:HTMLLoader=new HTMLLoader();
  var url:URLRequest=new URLRequest(html.url);
  htmlLoader.width=880;
  htmlLoader.height=(appHeight - 150);  //i figure out the height elsewhere
  htmlLoader.load(url);
  var holder:UIComponent=new UIComponent();
  holder.addChild(htmlLoader);
  win=PrintTitleWindow(PopUpManager.createPopUp(mainWindow, PrintTitleWindow, true));
  win.width=900;
  win.height=(appHeight - 50);
  win.addChild(holder);
  win.addContent(htmlLoader);
  PopUpManager.centerPopUp(win);
 }
}

Here is the JS and HTML I used. I'm adding these in here for laughs. I'm sure there is a better way to do this, but I'm tired and it is late.

private function getJavascript():String
{
 return 'function myOnMessage(aMessage) { print({ bUI: true, bSilent: false, bShrinkToFit: true }); } function myOnDisclose(cURL,cDocumentURL) { return true; } function myOnError(error, aMessage) { app.alert(error); } var msgHandlerObject = new Object(); msgHandlerObject.onMessage = myOnMessage; msgHandlerObject.onError = myOnError; msgHandlerObject.onDisclose = myOnDisclose; this.hostContainer.messageHandler = msgHandlerObject;';
}

private function getHtml():String
{
return '<html><head><script>function callPdfFunctionFromJavascript(arg) { pdfObject = document.getElementById("PDFObj");pdfObject.postMessage([arg]);}</script></head><body><object id="PDFObj" data="exported.pdf" type="application/pdf" width="100%" height="100%"></object></body></html>';
}

The PrintTitleWindow is a simple title window with the print button on it. The code to print is simple.

myHtmlLoader.window.callPdfFunctionFromJavascript('Print');

Eh Voila! I have a gigantor-print-button like so:

alt text http://www.cetola.net/wp-content/uploads/2010/03/print.png

Hitting that big purple print button is the same as hitting the print icon in the PDF toolbar. The difference for me is that my users, who could be elementary or middle-school kids, won't have to look around for the stupid button.

So, it's a long way around the block. Still, if you need to print and can't rely on that adobe toolbar button, here's your answer :) .