【问题标题】:Save base64 string as PDF at client side with JavaScript使用 JavaScript 在客户端将 base64 字符串保存为 PDF
【发布时间】:2012-07-10 01:38:19
【问题描述】:

所以我的问题是:我有一个 pdf 文件作为我从服务器获取的 base64 字符串。我想使用此字符串将 PDF 直接显示到浏览器,或者在单击链接时为其提供“另存为...”选项。这是我正在使用的代码:

<!doctype>
<html>
<head>
   <title>jsPDF</title>
   <script type="text/javascript" src="../libs/base64.js"></script>
   <script type="text/javascript" src="../libs/sprintf.js"></script>
   <script type="text/javascript" src="../jspdf.js"></script>

       <script type="text/javascript">

        function demo1() {
            jsPDF.init();
            jsPDF.addPage();
            jsPDF.text(20, 20, 'Hello world!');
            jsPDF.text(20, 30, 'This is client-side Javascript, pumping out a PDF.');

            // Making Data URI
            var out = jsPDF.output();
            var url = 'data:application/pdf;base64,' + Base64.encode(out);

            document.location.href = url;
         }
    </script>
</head>
<body>

<a href="javascript:demo1()">Run Code</a>

</body>
</html>

它在 Chrome 和 Safari 上运行良好。 Firefox 确实识别 pdf,但不显示它,因为 FF 需要存在扩展名,但在这种情况下 data-URI 没有。我在这里坚持的原因,如果 chrome 和 safari 让它工作,那么必须有 FF 和 IE 的解决方案

我知道有一些相关的问题,但不是确切的问题,现在也有点老了。我知道一种解决方法是在服务器端生成 pdf,但我想在客户端生成它。

所以请聪明的人,是否有可能通过一些黑客或额外的 JS 下载插件?

【问题讨论】:

  • 你好???有没有人对这个问题有一些答案..可能是约翰·雷西格 ;-)
  • @owsata,同样的问题!它只是打开窗口!你找到解决问题的方法了吗?请告诉我们。谢谢
  • @FabioMilheiro Nope 没有发现任何有用的东西。最终的结果是,因为浏览器处理数据:应用程序的想法不同,所以一开始并没有太多使用它。所以最后的手段->从服务器发送现成的pdf。
  • stackoverflow.com/a/16245768/7282741 这个解决了我的问题并节省了我的周末。

标签: javascript internet-explorer firefox pdf base64


【解决方案1】:

您可以创建如下所示的锚点来下载 base64 pdf:

<a download=pdfTitle href=pdfData title='Download pdf document' />

其中的 pdfData 强>是base64编码的PDF等的 “数据:应用/ PDF; BASE64,JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4 + CnN0cmVhbQp4nO1cyY4ktxG911fUWUC3kjsTaBTQ1Ytg32QN4IPgk23JMDQ2LB / 0 + 2YsZAQzmZk1PSPIEB ...” P>

【讨论】:

  • 你的这些信息帮助我在 Salesforce Lightning 中完成了它,使用这个字符串你可以在按钮点击时进行文件下载
  • 在 C# 中,当您返回 FileContentResult 时,它会保留以 base64 编码的文件,但是没有任何迹象表明它也没有 mime 类型。所以为了在客户端正确实现它,我必须附加数据:应用程序/pdf;base64,在字符串前面,它起作用了!
  • 这帮助我避免为了下载文件而创建额外的后端端点,谢谢!!
  • @OssSilva 很高兴听到这个消息!
【解决方案2】:

您可以使用此功能从 base64 下载文件。

function downloadPDF(pdf) {
const linkSource = `data:application/pdf;base64,${pdf}`;
const downloadLink = document.createElement("a");
const fileName = "abc.pdf";
downloadLink.href = linkSource;
downloadLink.download = fileName;
downloadLink.click();}

此代码将使用 href 和下载文件制作一个锚标记。如果你想使用按钮,那么你可以在你的按钮点击时调用点击方法。

希望对你有帮助,谢谢

【讨论】:

    【解决方案3】:

    您应该可以使用下载文件

    window.open("data:application/pdf;base64," + Base64.encode(out));
    

    【讨论】:

    • 不,Chrome 和 FF 直接下载但不分配扩展名。 Safari 打开 PDF 并在浏览器中显示它哇。 IE 会打开一个标题为“application/octet-stream”的新标签页,仅此而已...
    • 我使用数据结构进行了直接重定向,但是它需要一个容器或一种机制来将数据解析为可用的格式(例如:iFrame)。然而,我还没有按照规定测试这种机制。
    【解决方案4】:

    我知道这个问题很老,但也想完成这个并在寻找时遇到了它。对于 Internet Explorer,我使用来自 here 的代码来保存 Blob。要从 base64 字符串创建一个 blob,这个网站上有很多结果,所以它不是我的代码,我只是不记得具体的来源:

    function b64toBlob(b64Data, contentType) {
        contentType = contentType || '';
        var sliceSize = 512;
        b64Data = b64Data.replace(/^[^,]+,/, '');
        b64Data = b64Data.replace(/\s/g, '');
        var byteCharacters = window.atob(b64Data);
        var byteArrays = [];
    
        for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
            var slice = byteCharacters.slice(offset, offset + sliceSize);
    
            var byteNumbers = new Array(slice.length);
            for (var 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;
    

    使用链接文件保护程序:

    if (window.saveAs) { window.saveAs(blob, name); }
        else { navigator.saveBlob(blob, name); }
    

    【讨论】:

    • 文件保护程序在 Safari 中也失败了 :(
    • 我在此链接stackoverflow.com/questions/34436133/… 上发布了解决方案,该解决方案在 IE、CHROME、FF 中运行良好。如果此解决方案对您有帮助,请尝试投票
    【解决方案5】:

    dataURItoBlob(dataURI) {
          const byteString = window.atob(dataURI);
          const arrayBuffer = new ArrayBuffer(byteString.length);
          const int8Array = new Uint8Array(arrayBuffer);
          for (let i = 0; i < byteString.length; i++) {
            int8Array[i] = byteString.charCodeAt(i);
          }
          const blob = new Blob([int8Array], { type: 'application/pdf'});
          return blob;
        }
    
    // data should be your response data in base64 format
    
    const blob = this.dataURItoBlob(data);
    const url = URL.createObjectURL(blob);
    
    // to open the PDF in a new window
    window.open(url, '_blank');

    【讨论】:

    • 我在网上找了几个解决方案,只有这个对我有用,谢谢 Manas Sahu 先生
    • 我很高兴@RicardoLerma。
    【解决方案6】:

    您不需要任何库。 JavaScript 已经支持这一点。这是我的端到端解决方案。

    const xhr = new XMLHttpRequest();
    xhr.open('GET', 'your-end-point', true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    xhr.responseType = 'blob';
    xhr.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
           if (window.navigator.msSaveOrOpenBlob) {
               window.navigator.msSaveBlob(this.response, "fileName.pdf");
            } else {
               const downloadLink = window.document.createElement('a');
               const contentTypeHeader = xhr.getResponseHeader("Content-Type");
               downloadLink.href = window.URL.createObjectURL(new Blob([this.response], { type: contentTypeHeader }));
               downloadLink.download = "fileName.pdf";
               document.body.appendChild(downloadLink);
               downloadLink.click();
               document.body.removeChild(downloadLink);
            }
        }
    };
    xhr.send(null);
    

    这也适用于 .xls.zip 文件。您只需将文件名更改为fileName.xlsfileName.zip。这取决于您的情况。

    【讨论】:

      猜你喜欢
      • 2013-06-04
      • 1970-01-01
      • 1970-01-01
      • 2021-03-13
      • 2017-01-29
      • 1970-01-01
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多