JavaScriptから直接PDFを印刷する


93

HTMLでPDFのリストを作成しています。リストには、ダウンロードリンクと印刷ボタン/リンクを含めたいと思います。ユーザーがPDFを表示したりPDFビューアを開いたりせずにPDFの[印刷]ダイアログを直接開く方法はありますか?

PDFを非表示のiframeにダウンロードして、JavaScriptで印刷するようにトリガーするバリエーションはありますか?

回答:


56

以下のコメントに基づいて、最新のブラウザでは動作しません
この質問は、あなたに役立つかもしれないアプローチを示しています:埋め込みPDFのサイレント印刷

<embed>タグを使用してPDFをドキュメントに埋め込みます。

<embed
    type="application/pdf"
    src="path_to_pdf_document.pdf"
    id="pdfDocument"
    width="100%"
    height="100%" />

次に.print()、PDFの読み込み時にJavaScriptの要素のメソッドを呼び出します。

function printDocument(documentId) {
    var doc = document.getElementById(documentId);

    //Wait until PDF is ready to print    
    if (typeof doc.print === 'undefined') {    
        setTimeout(function(){printDocument(documentId);}, 1000);
    } else {
        doc.print();
    }
}

埋め込みを非表示のiframeに配置してそこから印刷することで、シームレスなエクスペリエンスを実現できます。


3
このソリューションでは...私はクロム、FFのために拒否された権限の仕事を取得していますしない
user1428716

8
埋め込まれたドキュメントが別のドメインにある場合、これは機能しません。
nullability 2015

5
レンダリング時に印刷するためにPDFにJavaScriptを追加するだけの方が簡単です。これがGoogleドキュメントの機能です。この方法では、ブラウザーがそれをロードして印刷するか、アドビのプラグインを使用します。
Rahly

2
あなたはおそらくそれをググることができますが、それはすべて、PDFに追加された新しいスクリプトオブジェクトであり、javascriptは単に「window.print()」です
Rahly

6
ええ、print()メソッドが定義されていないすべてのブラウザーで問題が発生しています。この方法は時代遅れですか?他の解決策はありますか?
Jacob Ensor 2017年

38

iframeからPDFを印刷する機能です。

PDFのURLを関数に渡すだけです。PDFが読み込まれると、iframeが作成され、印刷がトリガーされます。

この関数はiframeを破棄しないことに注意してください。代わりに、関数が呼び出されるたびに再利用します。印刷が完了するまでiframeが必要であり、printメソッドはコールバックサポートを備えていないため(私が知る限り)、iframeを破棄するのは困難です。

printPdf = function (url) {
  var iframe = this._printIframe;
  if (!this._printIframe) {
    iframe = this._printIframe = document.createElement('iframe');
    document.body.appendChild(iframe);

    iframe.style.display = 'none';
    iframe.onload = function() {
      setTimeout(function() {
        iframe.focus();
        iframe.contentWindow.print();
      }, 1);
    };
  }

  iframe.src = url;
}

3
あなたが私に大きな問題を解決するのを助けてくれて、あなたに感謝します:なしではsetTimeout、印刷機能は時々失敗します。なぜだかわからず、誰かがそれを見つけてくれることを願っています。
エヴァン・フ

printメソッドにはコールバックサポートがありますが、2014年にこの回答を書いたときはまだ広くサポートされていませんでした。すべての主要なデスクトップブラウザの最新バージョンがサポートしていonafterprintます。最初の印刷ダイアログが表示される前にiframe URLが既にスワップアウトされているため、iframeを再利用すると、誰かが2つのボタンをすばやくクリックして2番目のPDFを2回印刷するという競合状態が発生する可能性があることを少し心配しています。
マークアメリー

18

http://printjs.crabbly.com/からPrint.jsをダウンロードします

$http({
    url: "",
    method: "GET",
    headers: {
        "Content-type": "application/pdf"
    },
    responseType: "arraybuffer"
}).success(function (data, status, headers, config) {
    var pdfFile = new Blob([data], {
        type: "application/pdf"
    });
    var pdfUrl = URL.createObjectURL(pdfFile);
    //window.open(pdfUrl);
    printJS(pdfUrl);
    //var printwWindow = $window.open(pdfUrl);
    //printwWindow.print();
}).error(function (data, status, headers, config) {
    alert("Sorry, something went wrong")
});

3
IE、Edge、FirefoxでPDFを印刷しません。
Richard Collette

今日、jQuery getを使用してサーバーからPDFのバイトを取得し、次に上記のようにblobと 'createOvjectURL'を作成してこれを試しました。この場合、PrintJSは印刷ダイアログを表示しません。:)
woohoo 2018年

ワンクリックで複数のPDFファイルを印刷できますか?
Sunil Garg


6

この機能を使用してサーバーからPDFストリームをダウンロードしました。

function printPdf(url) {
        var iframe = document.createElement('iframe');
        // iframe.id = 'pdfIframe'
        iframe.className='pdfIframe'
        document.body.appendChild(iframe);
        iframe.style.display = 'none';
        iframe.onload = function () {
            setTimeout(function () {
                iframe.focus();
                iframe.contentWindow.print();
                URL.revokeObjectURL(url)
                // document.body.removeChild(iframe)
            }, 1);
        };
        iframe.src = url;
        // URL.revokeObjectURL(url)
    }

4

base64文字列からPDFを印刷するためのクロスブラウザーソリューション:

  • Chrome:印刷ウィンドウが開きます
  • FF:PDFを含む新しいタブが開かれる
  • IE11:開く/保存プロンプトが開かれる

const blobPdfFromBase64String = base64String => {
   const byteArray = Uint8Array.from(
     atob(base64String)
       .split('')
       .map(char => char.charCodeAt(0))
   );
  return new Blob([byteArray], { type: 'application/pdf' });
};

const isIE11 = !!(window.navigator && window.navigator.msSaveOrOpenBlob); // or however you want to check it

const printPDF = blob => {
   try {
     isIE11
       ? window.navigator.msSaveOrOpenBlob(blob, 'documents.pdf')
       : printJS(URL.createObjectURL(blob)); // http://printjs.crabbly.com/
   } catch (e) {
     throw PDFError;
   }
};

printPDF(blobPdfFromBase64String(base64String))

ボーナス-IE11の新しいタブでblobファイルを開く

サーバーでbase64文字列の前処理を実行できる場合は、それをいくつかのURLで公開し、printJS:)でリンクを使用できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.