使用Javascript、HTML5、AngularJS从浏览器打印嵌入式PDF
Print embedded PDF from browser with Javascript, HTML5, AngularJS
我正在从服务器将Base64编码的PDF作为字符串加载到我的JavaScript中。我的客户端应用程序使用AngularJS,HTML5。
我的HTML如下所示:
<div id="printablePdfContainer">
<iframe id="printablePdf" width="100%" height="100%"></iframe>
</div>
我的JavaScript如下:
var pdfName = 'data:application/pdf;base64,' + data[0].PrintImage;
var embeddedPdf = document.getElementById('printablePdf');
embeddedPdf.setAttribute('src', pdfName);
$scope.printDocument(embeddedPdf);
我的printDocument
函数如下:
$scope.printDocument = function() {
var test = document.getElementById('printablePdf');
if (typeof document.getElementById('printablePdf').print === 'undefined') {
setTimeout(function(){$scope.printDocument();}, 1000);
} else {
var x = document.getElementById('printablePdf');
x.print();
}
};
printDocument
函数取自堆栈溢出(Silent print an embedded PDF)中的一个预先存在的问题,该问题给出了打印嵌入式PDF的答案。然而,这似乎已经不起作用了。我总是对感到"不确定"
typeof document.getElementById('printablePdf').print === 'undefined'
检查。似乎.print
不存在什么的。
所以,我的问题是:如何在不打开弹出窗口的情况下,使用JavaScript打印HTML5中的嵌入式PDF?
这里也有答案:从javascript嵌入标签打印Pdf
经过大量研究,我将把我学到的东西发布在这里,供未来可能发现这一点的人使用。
PDF的显示方式因浏览器、浏览器版本、浏览器配置和操作系统而异。有很多变量,所以我将在这里讨论最常见的情况。
-
在所有浏览器上,我都无法通过Javascript调用任何类型的print()方法,只能使用PdfActions。OPENACTION将调用print。我使用iText将这些嵌入到PDF中。
-
Chrome使用Adobe的查看器,该查看器不允许访问任何类型的print()方法,但可以执行嵌入PDF中的PdfActions。因此,您可以在PDF中嵌入"OpenAction",并在从任何查看这些操作的应用程序打开PDF时打印PDF调用。
-
Firefox(高于某个版本,但都是最新版本)在Windows中使用Adobe查看器,该查看器也可以识别PdfActions。然而,在OSX中,它失去了对Adobe查看器的支持,转而使用在Firefox中烘焙的查看器(pdf.js)。它不支持PdfActions。
-
IE:我在IE上并没有做太多测试。主要是因为Firefox不能在OSX上运行后,我放弃了从Javascript打印PDF(这对我来说是一个要求)。
我的PDF是由我控制的服务器生成的,所以我最终在服务器中进行了服务更改,并添加了一个getPNG服务,该服务基于PDF生成使用的相同标记生成了一个PNG。浏览器处理图像的能力比PDF要好得多,我知道PDF正在使用,但我希望我能够重复使用PDF生成服务,因为它在我的代码中的其他地方也使用过。
这并不能回答问题,但这是我所掌握的全部信息。我对未来可能发现这一点的人的建议是:在这种情况下,如果可能的话,放弃PDF,变得更简单。否则,如果您知道如何在OSX中的FF预览pdf查看器中通过Javascript调用print(),请更新此问题。
-Phil
要打印base64 pdf,您需要避开这样一个事实:数据URI没有来源,因此被现代浏览器阻止。
请参阅MDN上日期URL页面上的注释:数据URL。
为了避免这种情况,必须直接引用同一个pdf(在这种情况下是否定的),或者将pdf转换为对象/blob url。
请参阅MDN关于创建对象/blob URL 的说明
function b64toBlob(b64Data, contentType) {
var byteCharacters = atob(b64Data)
var byteArrays = []
for (let offset = 0; offset < byteCharacters.length; offset += 512) {
var slice = byteCharacters.slice(offset, offset + 512),
byteNumbers = new Array(slice.length)
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i)
}
var byteArray = new Uint8Array(byteNumbers)
byteArrays.push(byteArray)
}
var blob = new Blob(byteArrays, { type: contentType })
return blob
}
var pdfObjectUrl = URL.createObjectURL(b64toBlob(data[0].PrintImage, 'application/pdf'))
var embeddedPdf = document.getElementById('printablePdf')
embeddedPdf.setAttribute('src', pdfObjectUrl)
// Then to print
embeddedPdf.contentWindow.print()
一旦数据位于对象URL内,浏览器安全性就不会阻止contentWindow。print方法将存在于iframe的contentWindow中。
- 有可能过滤来自嵌入式YouTube的声音吗
- 使用javascript将动态表从一个html页面打印到另一个html页
- JavaScript打印功能使日历停止工作
- esri javascript异步打印
- 文本框不是从Javascript/Asp.net中的对话框中打印出来的
- jQuery/JavaScript在线公文包表单-打印样式表
- 如何打印嵌套对象的所有值
- 在终端中运行 JavaScript 时(使用 rhino),如何使用 print() 函数在一行中打印
- WebResources嵌入式资源和Javascript如何在另一个嵌入式资源中使用它们
- 打印预览没有应用程序页眉和页脚的html表格
- 正在打印图表上的文本
- Javascript嵌入式图像资源
- Rhino打印功能
- javascript从任何嵌入式flash视频中发现.flvurl
- 在通过child.print()打印之前,我如何等待图像加载到我的新窗口中
- 如何用javascript打印php数组
- 嵌套在嵌入式红宝石上,不打印任何内容
- 使用Javascript、HTML5、AngularJS从浏览器打印嵌入式PDF
- 使用嵌入式javascript自动打印pdf
- microsoft Edge -嵌入式PDF -如何打印