javascript - 在 Firefox 中打印 PDF

标签 javascript jquery firefox printing pdf-generation

如何在 Firefox 中打印 PDF?

此功能在 Chrome 中有效,但在 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: Permission denied to access property "print"

最佳答案

Firefox:访问属性“打印”的权限被拒绝

这是一个 bug in firefox .在本地可以通过转到 about:config 并将 pdfjs.disabled 的属性设置为 true 来禁用它。唯一可能的解决方法是使用服务器端脚本并修改 pdf。使用 php 你可以使用 fpdf并嵌入 extensions实现 js(包括 print() 函数)或简单地将 pdf 转换为图像,返回 url 并打印它。你可以使用 FPDI修改现有的pdf。我将举例说明我是如何让它与 PHP 一起工作的。

使用 FPDI 使用内联 javascript(自动打印)生成 PDF 文件|和 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');

现在您只需将生成的 pdf 附加到您的页面,包含的 javascript 将调用 print() 函数。您甚至不必再手动调用它。但是,在 Firefox 中,这仅适用于 visibility: hidden 而不适用于 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:安全错误(跨源)

pdf 应位于同一主机上。在我的测试中,Firefox 与其他域没问题,但 chrome 给我带来了跨源错误。


Firefox:打印页面仅包含about:blank

您将在 firefox ( jsfiddle ) 中得到一个空白页面,因为它会在加载任何内容之前打印 iframe。提到的方法如 $(document).onload() 不会有帮助,因为它们只等待 DOM 加载并且 setTimeout() 仍然会导致错误,因为您不知道加载 iFrame 需要多长时间。

您可以使用 jQuery 的 load() 简单地解决这个问题。 ( doc ) 这将使您有可能使用回调函数作为参数。

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.

代码示例 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();
    });
}

或者,您可以直接创建一个 jQuery 对象并使用 jQuery 的 on() ( doc ) 来附加任何事件处理程序。

代码示例 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();
    });
}

关于javascript - 在 Firefox 中打印 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33254679/

相关文章:

javascript - ramda js 使用reduce 连接值

java - 评论后如何重定向到同一页面

javascript - 转换 JavaScript 数组

javascript - 如何获得两点之间的一组子点?

jquery - 如何在 Webpack Angular 2 中包含 jQuery 和 Semantic-ui

javascript - element.currentSrc 在除 Firefox 之外的所有浏览器中返回 URL

firefox - 跨多台机器的浏览器同步

javascript - 如何防止div容器被调整大小

javascript - 我如何扩展一个 javascript 对象,以便在 native 没有 outerHTML 的浏览器中,我可以定义它?

firefox - 从 Web Workers 访问 IndexedDB