首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从javascript触发base64编码PDF的打印预览

从javascript触发base64编码PDF的打印预览
EN

Stack Overflow用户
提问于 2016-11-07 16:01:52
回答 2查看 12.2K关注 0票数 10

我已经找了很长一段时间试图找到一种方法来做堆栈溢出,但找不到合适的答案。我需要能够通过base64编码的字符串在新窗口或iframe中加载PDF,并在加载后立即触发它的打印预览。我可以轻松地使用这两种方法加载PDF,但实际上无法正确地显示打印预览。以下是我尝试过的:

  1. 在新窗口中使用embed元素。即使在加载了内容之后,调用window.print()也是空的。
  2. 使用一个隐藏的、使用src="data:application/pdf;base64,JVBERi0..."动态创建的src="data:application/pdf;base64,JVBERi0..."并调用myFrame.contentWindow.print()。但这给CORS带来了一个错误。我不知道为什么,因为我没有通过iframe加载一个新域,只是内容。
  3. 打开一个只有像#2中的iframe元素的新窗口,并在整个窗口上调用一个打印。这也显示了一个空白的白页。
  4. 使用数据uri打开一个新窗口并打印出来。window.open('data:application/pdf;base64,JVBERi0...').print();。这也不起作用,因为它根本不显示打印预览。我也尝试过用setTimeout来延迟它,但这也没有任何作用。

在这一点上,我非常困惑为什么这些都不起作用,特别是因为在Chrome中,它显示的自定义菜单栏如下:

如果我点击实际的打印图标,打印预览是完美的。无论Chrome是做什么,当我点击那个按钮,这正是我想要完成的。是否有触发该功能的方法?还是有别的方法来实现我想要的?为了澄清这一点,我只需要在Chrome上工作,我不需要担心其他浏览器。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-13 09:09:31

以下是第3点的解决方案:

打开一个新窗口,其中只有一个iframe元素,如#2中的元素,并在整个窗口上调用一个打印。这也显示了一个空白的白页。

在您的例子中,它抛出了CORS错误,因为它看起来像是为base64String而不是给URL提供的src。这里是你能做的

  1. 带上你的base64String,把它转换成一个小块
  2. 从Blob生成一个URL
  3. 向iframe提供生成的URL。
  4. 之后,您可以使用iframe.contentWindow.print()打印内容;

下面是将base64转换为Blob的代码

代码语言:javascript
运行
复制
'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);

blobUrl用于Iframe的src,一旦完成,就可以在iframe上调用print(),如下所示

代码语言:javascript
运行
复制
const iframeEle = document.getElementById("Iframe");
if (iframeEle) {
    iframeEle.contentWindow.print();
}

希望这能帮上忙。

关于base64 to Blob的更多详细信息,请参阅Creating a Blob from a base64 string in JavaScript

票数 17
EN

Stack Overflow用户

发布于 2019-09-03 07:50:47

你可以用这个,

函数"printPreview(binaryPDFData)",获得打印预览对话框的二进制pdf数据。

代码语言:javascript
运行
复制
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;
};
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40469412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档