直接从JavaScript打印PDF


93

我正在建立HTML格式的PDF清单。在列表中,我想包含一个下载链接和一个打印按钮/链接。有什么方法可以直接打开PDF的“打印”对话框,而无需用户查看PDF或打开PDF查看器?

将PDF下载到隐藏的iframe中并触发使用JavaScript进行打印,是否有些变化?

Answers:


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
此解决方案无法正常工作...我无法获得Chrome,FF的权限
user1428716

8
如果嵌入式文档位于其他域中,则此方法将无效。
nullability,2015年

5
只需将javascript添加到pdf即可在呈现时进行打印。这就是Google文档的功能。这样,浏览器可以加载并打印它,或者是Adobe插件。
拉希(Rahly)

2
您可能会用谷歌搜索它,但仅此而已,就是将一个新的脚本对象添加到pdf中,其中javascript只是“ window.print()”
Rahly

6
是的,我在所有未定义print()方法的浏览器中都遇到问题。这种方法过时了吗?还有其他解决方案吗?
Jacob Ensor

38

这是从iframe打印PDF的功能。

您只需要将PDF的URL传递给函数。加载PDF后,它将创建一个iframe并触发打印。

请注意,该函数不会破坏iframe。而是在每次调用函数时重用它。很难销毁iframe,因为直到完成打印才需要使用iframe,并且print方法没有回调支持(据我所知)。

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可能会引起竞争状况,因为有人会快速单击两个按钮并最终两次打印第二个PDF,这是因为iframe URL在第一个打印对话框出现之前已经被换出了。
Mark Amery

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。
理查德·科莱特

今天尝试使用jQuery get从服务器获取pdf字节,然后如上所述创建blob和'createOvjectURL'。在这种情况下,PrintJS不显示打印对话框。:)
woohoo

一次单击即可打印多个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:)中的链接

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.