从javascript触发base64编码PDF的打印预览
我已经环顾了stackoverflow一段时间,试图找到一种方法来解决这个问题,但找不到合适的答案。我需要能够通过base64编码字符串在新窗口或iframe中加载PDF,并在加载后立即触发PDF的打印预览。我可以使用这两种方法轻松地加载PDF,但实际上无法让它正确显示打印预览。以下是我尝试过的:从javascript触发base64编码PDF的打印预览,javascript,html,pdf,iframe,Javascript,Html,Pdf,Iframe,我已经环顾了stackoverflow一段时间,试图找到一种方法来解决这个问题,但找不到合适的答案。我需要能够通过base64编码字符串在新窗口或iframe中加载PDF,并在加载后立即触发PDF的打印预览。我可以使用这两种方法轻松地加载PDF,但实际上无法让它正确显示打印预览。以下是我尝试过的: 使用在新窗口中嵌入元素。调用window.print()是空的,即使在加载内容之后也是空的 使用动态创建的隐藏的iframe和src=“data:application/pdf;base64,JVBE
在新窗口中嵌入元素。调用window.print()
是空的,即使在加载内容之后也是空的
iframe
和src=“data:application/pdf;base64,JVBERi0…”
并调用myFrame.contentWindow.print()
。但这会产生一个CORS错误。我不知道为什么,因为我没有通过iframe加载新域,只是加载内容iframe
元素(如#2中的元素)的新窗口,并在整个窗口上调用打印。这也显示了一个空白的白色页面setTimeout
来延迟它,但这也没用如果我点击实际的打印图标,打印预览就完美了。当我点击那个按钮时,Chrome正在做的事情正是我想要完成的。是否存在触发该功能的方法?还是有其他方法来实现我想要的?为了澄清,我只需要在Chrome中使用它,我不需要担心其他浏览器。下面是第3点的解决方案: 打开一个只有iframe元素(如#2中的元素)的新窗口,并在整个窗口上调用打印。这也显示了一个空白的白色页面 在您的例子中,它抛出了CORS错误,因为对于iframe src,您给出的是base64String,而不是URL。这是你能做的
iframe.contentWindow.print()打印内容李>
下面是将base64转换为Blob的代码
'use strict';
const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize),
byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: contentType });
return blob;
}
const contentType = "application/pdf",
b64Data = "YourBase64PdfString", //Replace this with your base64String
blob = this.b64toBlob(b64Data, contentType),
blobUrl = URL.createObjectURL(blob);
希望这有助于
有关base64 to Blob的更多详细信息,请参见此处
函数“打印预览(binaryPDFData)”获取二进制pdf数据的打印预览对话框
printPreview = (data, type = 'application/pdf') => {
let blob = null;
blob = this.b64toBlob(data, type);
const blobURL = URL.createObjectURL(blob);
const theWindow = window.open(blobURL);
const theDoc = theWindow.document;
const theScript = document.createElement('script');
function injectThis() {
window.print();
}
theScript.innerHTML = `window.onload = ${injectThis.toString()};`;
theDoc.body.appendChild(theScript);
};
b64toBlob = (content, contentType) => {
contentType = contentType || '';
const sliceSize = 512;
// method which converts base64 to binary
const byteCharacters = window.atob(content);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {
type: contentType
}); // statement which creates the blob
return blob;
};
printPreview=(数据,类型='application/pdf')=>{
设blob=null;
blob=this.b64toBlob(数据,类型);
const blobURL=URL.createObjectURL(blob);
const theWindow=window.open(blobURL);
const theDoc=theWindow.document;
const theScript=document.createElement('script');
函数injectThis(){
window.print();
}
theScript.innerHTML=`window.onload=${injectThis.toString()};`;
doc.body.appendChild(脚本);
};
b64toBlob=(内容,内容类型)=>{
contentType=contentType | |“”;
常量切片大小=512;
//将base64转换为二进制的方法
const byteCharacters=window.atob(content);
常量字节数组=[];
for(让offset=0;offset
您成功地使它工作了吗?我也试过同样的方法,但似乎什么都不管用work@db306不,我真的不认为这是可能的,我已经尝试了我能想到的一切。Chrome中的PDF查看器实际上是一个插件,我认为不可能通过javascript与之交互。我认为使用PDF.js可以实现这一点,但我还没有时间尝试和实现它。实际上,我成功地将它打印到弹出窗口上,但是,该函数会很快被触发,并且由于每个浏览器都有不同的阅读器,我无法在PDF格式化程序上添加事件侦听器。我能让它工作的唯一方法是将pdf文件保存在服务器上,在隐藏的iframe上提供pdf,并在加载iframe后打印。希望这对别人有帮助。感谢使用iframe在chrome上的这些作品,但是我在Safari上遇到了麻烦,它试图在呈现PDF之前打印,而onload无法正常工作。这非常有效。我只需要添加一个setTimeout(),以便浏览器有时间呈现PDF。否则,它将只打印一个空白页。这将返回带有原点的阻止的帧”http://localhost:3000“从访问交叉原点帧开始。
我的错误。我有Allow Origin=*
谢谢你的解决方案,这项工作,但我不知道什么是sliceSize,为什么?这在Chrome和Firefox中工作得很好,但在IE中没有。IE中是否有任何修复。无法将blob url添加到IE中的窗口。是否要在打印后自动关闭?我对图像也有类似的处理方法,我可以使用window.close()
来实现这一点,但当我将window.close()
放在上面的代码中时,它会在我有机会打印之前关闭窗口,即使设置了很短的设置超时时间。
printPreview = (data, type = 'application/pdf') => {
let blob = null;
blob = this.b64toBlob(data, type);
const blobURL = URL.createObjectURL(blob);
const theWindow = window.open(blobURL);
const theDoc = theWindow.document;
const theScript = document.createElement('script');
function injectThis() {
window.print();
}
theScript.innerHTML = `window.onload = ${injectThis.toString()};`;
theDoc.body.appendChild(theScript);
};
b64toBlob = (content, contentType) => {
contentType = contentType || '';
const sliceSize = 512;
// method which converts base64 to binary
const byteCharacters = window.atob(content);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {
type: contentType
}); // statement which creates the blob
return blob;
};