我的使用要求是从MongoDB GRIDFS中读取到pdf文件,然后在html前端展示。后端用的是python Django。
网上查了几天资料,最后发现其实很简单。
直接显示服务器上的pdf文件这个很容易,但是如果是存储在数据库中的二进制文档呢?其实也很简单,只是我看了文章后把自己搞复杂了。
一开始瞧不上人家用iframe,撞了几天南墙之后,还是觉得iframe最好。把所有问题轻松解决了。
服务器端
服务器端要做的就是把pdf文档读取出来,返回给前端。这里也绕了很多弯。其实以fileresponse返回pdf文档就可以了,不需要去进行各种编码。
从gridFS读取到文件后,进行如下操作:
bufr = io.BytesIO(file_content)
response = FileResponse(bufr, content_type='application/pdf')
ss=f'inline; filename={fileid}.pdf'
#response['Content-Disposition'] = f'attachment;filename="{file_name }"'
response['Content-Disposition'] = ss
return response
这样就可以在前端看到pdf文件了。对于电脑版的浏览器,会直接打开浏览pdf。在手机上,安卓会直接下载,苹果会直接打开。
而我想要的效果是都是直接打开,然后,用户可以自行从打开的界面中选择下载保存。
因此想到用pdf.js,最后发现用和不用都可以实现。
web前端
前端先引用pdf.js
<script src="../static/app/scripts/pdfjs/build/pdf.mjs" type="module"></script>
<link rel="stylesheet" href="../static/app/scripts/pdfjs/web/viewer.css">
<script src="../static/app/scripts/pdfjs/web/viewer.mjs" type="module"></script>
再先放个iframe:
<div id="divPdfViewPanel" style="margin: 5px;">
<iframe id="framePdfViewPanel" width="100%" height="800px;"></iframe>
</div>
最后就是关键的src属性的处理。
由于服务器返回的不是磁盘文件,因此需要通过接口来请求。
src属性支持接口请求。
直接将请求到的fileresponse传递给src属性,可以实现使用浏览器原生功能展现pdf:
fileURL = 'getpdfstream?fileid=' + fid + '&re_url=' + re_url;
document.getElementById("framePdfViewPanel").src=fileURL; //这里虽然没有使用pdf.js但是也成功了
使用览器原生功能展现效果如下:
将pdf.js的viewer.html页面传递给src属性,将上述代码注释掉:
fileURL = 'http://localhost:55220/bulletin/getpdfstream?fileid=' + fid + '&re_url=' + re_url;
fileURL = encodeURIComponent(fileURL);
//window.open('../static/app/scripts/pdfjs/web/viewer.html?file=' +fileURL); //打开新窗口显示,成功,效果不好,留下空白页面
document.getElementById("framePdfViewPanel").src='../static/app/scripts/pdfjs/web/viewer.html?file=' +fileURL;// 这里使用了pdf.js,成功了
使用pdf.js展示的效果如下,与原生的相比,工具栏不一样。
两者都能浏览大文件。
在手机端的效果暂未测试。