直接从JavaScript打印PDF

直接从JavaScript打印PDF,javascript,pdf,Javascript,Pdf,我正在建立一个HTML格式的PDF列表。在列表中,我想包括一个下载链接和一个打印按钮/链接。是否有一些方法可以直接打开PDF的打印对话框,而不让用户看到PDF或打开PDF查看器 将PDF下载到隐藏的iframe并触发它使用JavaScript打印的一些变体? 现场演示 这可能是你想要的,但我看不出这有什么意义,因为现代浏览器包括这样的功能,而且它在低功耗设备上运行速度非常慢,比如移动设备,顺便说一句,移动设备有自己的优化插件和应用程序。根据下面的评论,它在现代浏览器中不再有效。 这个问题展示了一

我正在建立一个HTML格式的PDF列表。在列表中,我想包括一个下载链接和一个打印按钮/链接。是否有一些方法可以直接打开PDF的打印对话框,而不让用户看到PDF或打开PDF查看器

将PDF下载到隐藏的iframe并触发它使用JavaScript打印的一些变体?

现场演示


这可能是你想要的,但我看不出这有什么意义,因为现代浏览器包括这样的功能,而且它在低功耗设备上运行速度非常慢,比如移动设备,顺便说一句,移动设备有自己的优化插件和应用程序。

根据下面的评论,它在现代浏览器中不再有效。
这个问题展示了一种可能对您有帮助的方法:

它使用
标记将PDF嵌入文档:

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

您可以将嵌入内容放置在隐藏的iframe中并从中打印出来,给您带来无缝体验。

这里有一个从iframe打印PDF的函数

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

请注意,该函数不会破坏iframe。相反,每次调用函数时,它都会重用它。销毁iframe很困难,因为它在打印完成之前是必需的,而且print方法没有回调支持(据我所知)


从下载Print.js


用于从base64字符串打印pdf的跨浏览器解决方案:

  • Chrome:打印窗口已打开
  • FF:打开带有pdf的新选项卡
  • IE11:打开/保存提示

奖金-在IE11的新选项卡中打开blob文件


如果您能够在服务器上对base64字符串进行一些预处理,您可以在某个url下公开它,并使用
printJS
:)中的链接我使用此功能从服务器下载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)
    }

您可以使用fetch下载pdf文件,并使用print.js打印它

                          fetch("url")
                            .then(function (response) {

                                response.blob().then(function (blob) {
                                    var reader = new FileReader();
                                    reader.onload = function () {

                                        //Remove the data:application/pdf;base64,
                                        printJS({
                                            printable: reader.result.substring(28),
                                            type: 'pdf',
                                            base64: true
                                        });
                                    };
                                    reader.readAsDataURL(blob);
                                })
                            });

此解决方案不起作用。。。我的Chrome权限被拒绝,如果嵌入的文档位于不同的域中,这将不起作用。只需将javascript添加到pdf中,即可在呈现时打印。谷歌文档就是这样做的。这种方式要么是浏览器加载并打印它,要么是adobe插件。是的,我在所有未定义print()方法的浏览器上都遇到了问题。这种方法过时了吗?还有其他解决方案吗?这已经不起作用了。Chrome最新版本,相同域上的PDF@nullability如果您找不到解决方法,请编辑并明确说明所写内容在过去是正确的,但不再有效,这样人们就不会浪费时间尝试。Pdf.js在打印大文档时也非常慢,比如80MB+不能在IE上打印Pdf,Edge或Firefox。今天尝试使用jQuery get从服务器获取pdf的字节,然后如上所述创建blob和“createOvjectURL”。在这种情况下,PrintJS不显示打印对话框。:)我可以一次点击打印多个pdf文件吗?只是尝试了演示页面。它在Firefox中打印我向您表示感谢,因为您帮助我解决了一个大问题:如果没有
setTimeout
,打印功能有时会失败。不知道为什么,希望有人会发现。print方法确实有回调支持,但在2014年编写此答案时还没有得到广泛支持。但现在是这样;所有主要桌面浏览器的最新版本都支持打印后的
onafterprint
。我有点担心重用iframe可能会引入竞争条件,即某人快速单击两个按钮,并最终打印第二个PDF两次,因为在第一个打印对话框出现之前,iframe URL已经被替换掉。
$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")
});
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))
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)
    }
                          fetch("url")
                            .then(function (response) {

                                response.blob().then(function (blob) {
                                    var reader = new FileReader();
                                    reader.onload = function () {

                                        //Remove the data:application/pdf;base64,
                                        printJS({
                                            printable: reader.result.substring(28),
                                            type: 'pdf',
                                            base64: true
                                        });
                                    };
                                    reader.readAsDataURL(blob);
                                })
                            });