使用 JavaScript 在客户端将 base64 字符串保存为 PDF
Posted
技术标签:
【中文标题】使用 JavaScript 在客户端将 base64 字符串保存为 PDF【英文标题】:Save base64 string as PDF at client side with JavaScript 【发布时间】: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。 Saving Base64 encoded PDF with Internet Explorer 10 and below的可能重复 ***.com/a/16245768/7282741 这个解决了我的问题并节省了我的周末。 【参考方案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 中也失败了 :( 我在此链接***.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.xls
或fileName.zip。这取决于您的情况。
【讨论】:
以上是关于使用 JavaScript 在客户端将 base64 字符串保存为 PDF的主要内容,如果未能解决你的问题,请参考以下文章
如何将JavaScript数组信息导出到csv(在客户端)?
使用 JavaScript 在客户端将 base64 字符串保存为 PDF
typescript 对于博客 - 使用systemjs将Phoenix javascript客户端包含在Angular 2应用程序中