web-dev-qa-db-ja.com

Firefoxでの印刷PDF

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"
44
clarkk

Firefox:プロパティ「print」へのアクセス許可が拒否されました

これは firefoxのバグ です。ローカルでは、_about:config_に移動し、_pdfjs.disabled_のプロパティをtrueに設定することで無効にできます。可能な回避策は、サーバー側のスクリプトを使用してPDFを変更することです。 phpを使用すると、 fpdf を使用して extensions を埋め込み、jsを実装(print()関数を含む)するか、pdfを画像に変換してURLを返すことができます。それを印刷します。 [〜#〜] fpdi [〜#〜] を使用して、既存のPDFを変更できます。 PHPでどのように動作するかの例を示します。

[〜#〜] fpdi [〜#〜] および-を使用してPDFファイルをインラインjavascript(自動印刷)で生成) 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 )これにより、パラメータとしてコールバック関数を使用できるようになります。

「完全な」コールバックが提供される場合、後処理とHTML挿入が実行された後に実行されます。コールバックはjQueryコレクションの各要素に対して1回起動され、thisが各DOM要素に順番に設定されます。

コード例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 )を使用してイベントハンドラーをアタッチできます。

コード例2jsfiddle

_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();
    });
}
_
32
oshell

編集、更新

window.onload event、document.createElement()onload event、setTimeout()を使用して、duration2000に設定し、srcに要素を追加した後にiframedocumentを設定してみてください

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

4
guest271314

PDFはJavascriptをサポートしています。 PHPで生成されたPDFが作成され、FPDFを使用して動作させることができたときに、自動印刷機能が必要でした。

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

2
vrtech77

@clarkk私は私の提案が http://pdfmake.org/#/ を使用することである多くの人々からカバーされたより強力な何かを使用することをお勧めします。

私はこのpdfmakeをデータテーブルで使用しましたが、完全に機能します。テーブルから1万行以上を印刷する場合や、ブラウザのメモリが不足する場合は注意してください:)

私はしばらくこれを使用していませんが、iframeからpdfを印刷するために使用していたこれ...

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

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

セキュリティの問題を防ぐために、新しいiframeを作成せずに(cssのみで)印刷機能を実装できます。

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();
0
Pedram