Print PDF in Firefox

廉价感情. 提交于 2019-11-30 06:39:47

问题


How to print a PDF in Firefox?

This function works in Chrome but not in Firefox

function print_pdf(url){
    var id = 'iframe', html = '<iframe id="'+id+'" src="'+url+'" style="display:none"></iframe>';
    $('#main').append(html);
    $('#'+id).load(function(){
        document.getElementById(id).contentWindow.print();
    }
}

error

Error: Permission denied to access property "print"

回答1:


Firefox: Permission denied to access property "print"

This is a bug in firefox. Locally it can be disabled by going to about:config and set the property of pdfjs.disabled to true. Only possible workaround is to use a server-side script and modify the pdf. Using php you could use fpdf and embed extensions to implement js (inclunding the print() function) or simply convert the pdf to an image, return the url and print it. You could use FPDI to modify the existing pdf. I will give you an example on how I got it to work with PHP.

Generating a PDF file with inline javascript (autoprint) using FPDI and PDF_JS

require_once('fpdf.php');
require_once('fpdi.php');

class PDF_JavaScript extends FPDI {

    var $javascript;
    var $n_js;

    function IncludeJS($script) {
        $this->javascript=$script;
    }

    function _putjavascript() {
        $this->_newobj();
        $this->n_js=$this->n;
        $this->_out('<<');
        $this->_out('/Names [(EmbeddedJS) '.($this->n+1).' 0 R]');
        $this->_out('>>');
        $this->_out('endobj');
        $this->_newobj();
        $this->_out('<<');
        $this->_out('/S /JavaScript');
        $this->_out('/JS '.$this->_textstring($this->javascript));
        $this->_out('>>');
        $this->_out('endobj');
    }

    function _putresources() {
        parent::_putresources();
        if (!empty($this->javascript)) {
            $this->_putjavascript();
        }
    }

    function _putcatalog() {
        parent::_putcatalog();
        if (!empty($this->javascript)) {
            $this->_out('/Names <</JavaScript '.($this->n_js).' 0 R>>');
        }
    }
}

class PDF_AutoPrint extends PDF_JavaScript
{
    function AutoPrint($dialog=false)
    {
        //Open the print dialog or start printing immediately on the standard printer
        $param=($dialog ? 'true' : 'false');
        $script="print($param);";
        $this->IncludeJS($script);
    }

    function AutoPrintToPrinter($server, $printer, $dialog=false)
    {
        $script = "document.contentWindow.print();";
        $this->IncludeJS($script);
    }
}

$pdf=new PDF_AutoPrint();
$pdf->setSourceFile("mozilla.pdf");
//Open the print dialog
$tplIdx = $pdf->importPage(1, '/MediaBox');
$pdf->addPage();
$pdf->useTemplate($tplIdx, 10, 10, 90);
$pdf->AutoPrint(true);
$pdf->Output('generated.pdf', 'F');

Now you can simply append the generated pdf to your page and the included javascript will call the print() function. You do not even have to call it manually anymore. However, in firefox this will only work with visibility: hidden and not with display: none.

function print_pdf(url){
    var iFrameJQueryObject = $('<iframe id="iframe" src="'+url+'" style="visibility: hidden"></iframe>');
    $('#foo').append(iFrameJQueryObject);
}
print_pdf('mozilla_generated.pdf');

Chrome: Security Error (cross-origin)

The pdf should be located at the same host. Firefox was okay with other domains in my tests, but chrome gave me cross-origin errors.


Firefox: Printed page includes about:blank only

You will get an empty page in firefox (jsfiddle), because it will print the iframe before it has loaded any content. Mentioned methods like $(document).onload() won't help, since they only wait for the DOM to load and setTimeout() can still result in errors, since you do not know how long it takes the iFrame to load.

You can simply resolve this issue by using jQuery's load(). (doc) This will give you the possibility to use a callback function as parameter.

if a "complete" callback is provided, it is executed after post-processing and HTML insertion has been performed. The callback is fired once for each element in the jQuery collection, and this is set to each DOM element in turn.

Code Example 1

function print_pdf(url){
    var id = 'iframe', html = '<iframe id="'+id+'" src="'+url+'" style="display:none"></iframe>';
    $('body').append(html);
    // wait for the iFrame to fully load and call the print() function afterwards
    $('#' + id).load(function () {
        document.getElementById(id).contentWindow.print();
    });
}

Alternatively you could directly create an jQuery object and use jQuery's on() (doc) to attach any event handler.

Code Example 2 (jsfiddle)

function print_pdf(url){
    var iFrameJQueryObject = $('<iframe id="iframe" src="'+url+'" style="display:none"></iframe>');
    $('body').append(iFrameJQueryObject);
    iFrameJQueryObject.on('load', function(){
        $(this).get(0).contentWindow.print();
    });
}



回答2:


Edit, Updated

Try using window.onload event , document.createElement() , onload event , setTimeout() with duration set to 2000 , setting src of iframe after appending element to document

window.onload = function() {
    function print_pdf(url){
        var id = "iframe", frame = document.createElement("iframe");
        frame.setAttribute("id", id);
        frame.setAttribute("width", "800px");
        frame.setAttribute("height", "600px");
        frame.setAttribute("allowfullscreen", "true");
        frame.setAttribute("name", "printframe");
        document.body.appendChild(frame);
        frame.onload = function() {
          this.requestFullScreen = this.mozRequestFullScreen 
                                   || this.webkitRequestFullScreen;
          this.requestFullScreen();
          setTimeout(function() {
            print()
          },2000)
        }
        frame.setAttribute("src", url);
    }
    print_pdf("http://zeitreisen.zeit.de/wp-content/uploads/2014/09/pdftest2.pdf");
}

plnkr http://plnkr.co/edit/mHBNmc5mdM0YJRwRbYif?p=preview




回答3:


PDFs have Javascript support. I needed to have auto print capabilities when a PHP-generated PDF was created and I was able to use FPDF to get it to work:

http://www.fpdf.org/en/script/script36.php




回答4:


@clarkk i would recommend to use something more powerful which has been covered from many people my suggestion is to use http://pdfmake.org/#/ .

I have use this pdfmake in my datatables and it works absolutely perfect. Keep in mind if you print more then 10 000 rows from tables or something it run out the memory of the browser :)




回答5:


I haven't use this for a while, but this what I was used to do to print pdf's from an iframe...

function printfile() {
    window.frames['objAdobePrint'].focus();
    window.frames['objAdobePrint'].print();
}

<iframe src="urlOfPdf" name="objAdobePrint" id="objAdobePrint"></iframe>
<button onclick="printfile();">Print</button>



回答6:


You can implement print function without create new iframe (only with css) to prevent security problems:

var style = document.createElement("style");
style.setAttribute("media", "print"); //style.setAttribute("media", "screen,print");
style.appendChild(document.createTextNode(""));
document.head.appendChild(style);
var width = $("#printDiv").width();
var height = $("#printDiv").height();
style.sheet.insertRule("body { width: 210mm !important, height: 25.4mm !important; visibility: hidden; }", 0);
style.sheet.insertRule("#printDiv { visibility: visible; position: fixed !important;top: 5px;  left: 5px; width:" + width + "px;height:" + height + ";  page-break-after: avoid;}", 0);

window.focus();
window.print(true);
style.remove();



回答7:


Print a pdf with javascript or jquery

Create a iframe in html:

<iframe id="pdf-iframe">

Then change the src of that iframe and on load, print it:

$('#pdf-iframe').attr("src", pdf_url).load(function(){
    document.getElementById('pdf-iframe').contentWindow.print();
});

Or, you might want to try https://mozilla.github.io/pdf.js/



来源:https://stackoverflow.com/questions/33254679/print-pdf-in-firefox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!