我被困在我的应用程序的最后一点,我应该在PDF中显示用户表单,因为他们内置了pdf查看器,因此在桌面浏览器上工作正常,但对于Android / iOS,它不能用作pdf查看器。
所以我试图使用PDF.js来显示它,(老实说,这是非常广泛使用但文档缺乏),只有catch我正在获取base64格式的数据。 PDF.js在网站上有一个示例,它显示了如何呈现base64数据但不是PDF,因为显示PDF为“PDF”我需要使用他们的“viewer.html”但是不需要base64数据吗?
最接近我在堆栈溢出时来到Pdf.js: rendering a pdf file using base64...,但我不知道在PDFJS.getDocument(pdfAsArray)?
之后如何使用它。
遇到的其他链接是other link
我不想依赖Google /第三方PDF查看器,因为我不知道他们会支持多久。
答案 0 :(得分:0)
社区中没有关于此主题的端到端答案,所以这是我尝试在此处添加内容。 (也许它会帮助别人)
好的,PDF.js是在浏览器中显示PDF的一种方式,特别是当您不想依赖PDF插件安装时。就我而言,我的应用程序生成PDF格式的报告,可以在下载之前查看,但在手持设备上由于缺少PDF查看器插件而无法正常工作。
在我的情况下,PDF被发送以浏览 base64 字符串,我可以使用<object src="base64-data"...></object>
来显示PDF。这类似于Chrome / FF上的魅力,但切换到移动视图并停止工作。
<object type="application/pdf" id="pdfbin" width="100%" height="100%" title="Report.pdf">
<p class="text-center">Looks like there is no PDF viewer plugin installed, try one of the below approach...</p>
</object>
在上面的代码中,它会尝试显示PDF或回退到<p>
并显示错误消息。我计划在此时添加PDF查看器,PDF.js是选择,但无法显示它。有关使用Base64数据的PDF.js的一个示例显示了如何执行此操作但将其呈现为图像而非PDF,我无法找到解决方案,因此问题,这就是我所做的,
首先添加JavaScript代码以将base64转换为数组
转换为blob并使用PDF.js打包的viewer.html
文件将其显示为PDF
如果您想知道为什么使用base64数据,那么答案很简单我可以创建PDF,读取它,将数据发送到客户端并删除文件,我不必运行任何更干净的服务/ cron job删除生成的PDF文件
很少需要注意
- 下面的代码是使用Flask + Jinja2,如果你正在使用别的东西,改变在html中读取base64的方式
- viewer.html需要更改为需要js&amp; css文件位于正确的位置(默认情况下,它们的位置是相对的;您需要从静态文件夹中引用它们)
viewer.js
在预定义的位置查找pdf.worker.js
,如果找不到上述文件,则更改该错误。viewer.js
可能在这种情况下抛出file origin does not match viewer
错误作为快速修复注释抛出此错误的代码并查看是否解决了该问题(查找该错误) viewer.js)- 我不是下面代码的作者,我只是从不同的地方把它放在一起。
醇>
现在到代码(当用户点击带有id="open_id"
的按钮
<强> Jquery的强>
var pdfDataX = '{{ base64Pdf }}';
var BASE64_MARKER = ';base64,';
PDFJS.workerSrc = "{{ url_for('static', filename='js/pdf.worker.js') }}";
$('#open_id').click(function() {
PDFJS.disableWorker = true;
var pdfAsDataUri = "data:application/pdf;base64," + pdfDataX ;
PDFJS.workerSrc = "{{ url_for('static', filename='js/pdf.worker.js') }}";
// Try to show in the viewer.html
var blob = base64toBlob(pdfDataX, 'application/pdf');
var url = URL.createObjectURL(blob);
var viewerUrl = "{{ url_for('static', filename='viewer.html') }}" + '?file=' + encodeURIComponent(url);
$('#pdfViewer').attr('src', viewerUrl);
// Finish
var mdObj = $('#pdfbin');
mdObj.hide();
mdObj.attr('data', pdfAsDataUri);
mdObj.show();
$('#myModal').modal();
});
var base64toBlob = function(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = 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;
}
$('.save').click(function(e) {
e.preventDefault();
var blob = base64toBlob(pdfDataX, 'application/pdf');
saveAs(blob, 'abcd.pdf'); // requires https://github.com/eligrey/FileSaver.js/
return false;
});
<强> HTML 强>
<object type="application/pdf" id="pdfbin" width="100%" height="100%" title="Resume.pdf">
<p class="text-center">Looks like there is no PDF viewer plugin installed, try one of the below approach...</p>
<iframe id="pdfViewer" style="width: 100%; height: 100%;" allowfullscreen="" webkitallowfullscreen=""></iframe>
</object>
希望将来对其他人有用。