私が構築したいのは、ボタンをクリックすることでPDFファイルを開くことなく、印刷をトリガーしたいということです。
_+-----------+
| Print PDF |
+-----------+
^ Click *---------> printPdf(pdfUrl)
_
私が最初に試した方法は、iframeを使用することです。
_var $iframe = null;
// This is supposed to fix the onload bug on IE, but it's not fired
window.printIframeOnLoad = function() {
if (!$iframe.attr("src")) { return; }
var PDF = $iframe.get(0);
PDF.focus();
try {
// This doesn't work on IE anyways
PDF.contentWindow.print();
// I think on IE we can do something like this:
// PDF.document.execCommand("print", false, null);
} catch (e) {
// If we can't print it, we just open it in the current window
window.location = url;
}
};
function printPdf(url) {
if ($iframe) {
$iframe.remove();
}
$iframe = $('<iframe>', {
class: "hide",
id: "idPdf",
// Supposed to be a fix for IE
onload: "window.printIframeOnLoad()",
src: url
});
$("body").prepend($iframe);
}
_
これはSafari(デスクトップおよびiOS)およびChrome(Webkitに一般化できますか?).
Firefoxでは、PDF.contentWindow.print()
は_permission denied
_エラーで終了します(pdfが同じドメインからロードされた場合でも)。
IE(11)]では、onload
ハンドラーが機能していません。
さて、私の質問は、ユーザーに視覚的に開かずにPDFを印刷する別のより良い方法はありますか?
ここではクロスブラウザのことが重要です。できるだけ多くのブラウザをサポートする必要があります。
これを達成する最良の方法は何ですか?私のスタートは良いものですか?どのように完了するのですか?
私たちは2016年になりましたが、これはまだブラウザ間で実装するのが苦痛だと感じています。
[〜#〜] update [〜#〜]:これは link のページプロパティの編集を含むエレガントなソリューションの詳細最初のページで、ページを開くときにアクションを追加します。すべてのブラウザーで機能します(ブラウザーはアクションセクションに配置されたJavaScriptを実行するため)。 Adobe Acrobat Proが必要です。
2016年は印刷の問題に新たな進歩をもたらさないようです。同様の問題があり、印刷用のクロスブラウザを作成するには、 PDF.JS を使用して解決しましたが、ソースに1行追加する必要がありました(とにかくビルドするように求められます)。
アイデア:
viewer.html
ファイルは、豊富なインターフェースを備えたPDFをレンダリングし、印刷機能を含むものです。そのファイルに、遅延後にwindow.print()を単純にトリガーするJavaScriptにリンクを追加しました。ビューアーに追加されたリンク:
<script src="viewer.js"></script>
<!-- this autoPrint.js was added below viewer.js -->
<script src="autoPrint.js"></script>
</head>
autoPrint.js
javascript:
(function () {
function printWhenReady() {
if (PDFViewerApplication.initialized) {
window.print();
}
else {
window.setTimeout(printWhenReady, 3000);
}
};
printWhenReady();
})();
その後、iframeのsrcにviewer.html?file=
への呼び出しを配置して非表示にすることができます。 Firefoxの表示スタイルではなく、可視性を使用する必要がありました。
<iframe src="web/viewer.html?file=abcde.pdf" style="visibility: hidden">
結果:短い遅延の後に印刷ダイアログが表示され、PDFはユーザーから隠されました。
Chrome、IE、Firefoxでテスト済み。
過去数時間を費やしてこれを見つけ出し、ここで多くの検索を行ったことが、私が決定したことです...
印刷用のHTML5 Web API仕様 は、printing steps
のいずれかが beforeprint 、単純なイベント(キャンセル不可のイベント)を起動する必要があることを示します。印刷するドキュメントのウィンドウオブジェクト(およびネストされたブラウジングコンテキスト、iframeに関連)は、印刷前にドキュメントを変更できるようにします。このステップはブラウザ内部のものであり、調整できるものではありません。このプロセス中に、ブラウザの印刷ダイアログにファイルのプレビューが表示される場合があります(Chromeがこれを行います)...目的がファイルをビューアに表示しないことである場合、スタックする可能性があります。
これを達成するために最も近かったのは、コンテキストを提供するdata- *属性を含むボタンを持つindex.html
ファイルを作成することでした。 data-print-resource-uri
属性のpath/filename.extを独自のローカルファイルに変更します。
<!DOCTYPE html>
<html>
<head>
<title>Express</title>
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body>
<h1>Express</h1>
<p>Welcome to Express</p>
<button name="printFile" id="printFile" data-print-resource-uri="/binary/paycheckStub.pdf" data-print-resource-type="application/pdf">Print File</button>
<iframe name="printf" id="printf" frameborder="0"></iframe>
<script src="/javascripts/print.js"></script>
</body>
</html>
それからprint.js
ファイルでいくつか試してみましたが、まったく機能しませんでした(コメントで遊んでいたさまざまなものを残しています)。
// Reference vars
var printButton = document.getElementById('printFile');
var printFrame = document.getElementById('printf');
// onClick handler
printButton.onclick = function(evt) {
console.log('evt: ', evt);
printBlob('printf', printButton.getAttribute('data-print-resource-uri'), printButton.getAttribute('data-print-resource-type'));
}
// Fetch the file from the server
function getFile( fileUri, fileType, callback ) {
var xhr = new XMLHttpRequest();
xhr.open('GET', fileUri);
xhr.responseType = 'blob';
xhr.onload = function(e) {
// Success
if( 200 === this.status ) {
// Store as a Blob
var blob = new Blob([this.response], {type: fileType});
// Hang a URL to it
blob = URL.createObjectURL(blob);
callback(blob);
} else {
console.log('Error Status: ', this.status);
}
};
xhr.send();
}
function printBlob(printFrame, fileUri, fileType) {
// Debugging
console.log('inside of printBlob');
console.log('file URI: ', fileUri);
console.log('file TYPE: ', fileType);
// Get the file
getFile( fileUri, fileType, function(data) {
loadAndPrint(printFrame, data, fileType);
});
}
function loadAndPrint(printFrame, file, type) {
// Debugging
console.log('printFrame: ', printFrame);
console.log('file: ', file);
window.frames[printFrame].src = file;
window.frames[printFrame].print();
/*
// Setup the print window content
var windowContent = '<!DOCTYPE html>';
windowContent += '<html>'
windowContent += '<head><title>Print canvas</title></head>';
windowContent += '<body>'
windowContent += '<embed src="' + file + '" type="' + type + '">';
windowContent += '</body>';
windowContent += '</html>';
// Setup the print window
var printWin = window.open('','','width=340,height=260');
printWin.document.open();
printWin.document.write(windowContent);
printWin.document.close();
printWin.focus();
printWin.print();
printWin.close();
*/
}
Blob
を使用して適切に機能させることができれば、必要なクロスブラウザメソッドで最適に機能すると思います。
このトピックに関する参考になる参考文献をいくつか見つけました。