1.背景
后台返回了一个在线的pdf地点,需要我这边去做一个pdf的预览(需求1),而且支持配置是否可以下载(需求2),需要在当前页就能预览(需求3)。之前我写过一篇预览pdf的文章,但是当时后台返回的是blob流文件,如果你们的pdf也是以流文件的情势返回的,可以看这篇文章(超链接点进去就行)。
2.简单说下pdf预览的实现方式
- a.借助 <embed> / <iframe>标签
复制代码 这个是真的很简单,我直接贴在下面了,缺点是: 没办法阻止用户打印和下载pdf,所以我pass了这个方案
- <embed
- type="application/pdf"
- :src="pdfUrl"
- width="800"
- height="600" />
复制代码- <iframe
- :src="pdfUrl"
- width="800"
- height="600" />
复制代码 实现效果:
b.利用vue插件vue-pdf来渲染(应该尚有一些其他的插件也可以利用,各人自己研究下实现的效果把)
这个方案我已经试了且用到项目上了,但是感觉很丑,跟浏览器打开pdf的效果差别很大,原因是这个插件大概得原理是把pdf转成了图片然后利用canvas来渲染的,然后很多东西都没有,就被我pass了。你可以想象一下你的pdf,然后你截图放进你网页上的感觉,就差不多是这个效果了,图片我忘记保存了,各人脑补一下
我找了个图,这个其实别人还做了一些其他的渲染,好比下面的也是他自己写的。我感觉是没这么悦目的,所以就抛弃了这个
c.利用pdf.js预览
我以为预览pdf这一块还是得用pdf.js,真的很成熟,样式也还是很给力的,然后想要改成什么样就可以改成什么样,由于源码在你手上。
缺点:稍微麻烦点,需要处理跨域的问题(但是如果你的网站、pdf文件地点位置,后台返回的pdf位置都在同一个域名下的话,就不需要处理)。且大概需要知道一点运维的知识,不然很大概你在本地能运行乐成,但是到线上大概访问不到
3.利用pdf.js预览pdf
a.到官网去下载pdf.js
建议下第二个!!!(别问我为啥,由于我下了第一个来写demo发现有报错,又踩坑了)
b.解压之后直接丢到项目中的public文件夹下面去
c.写一个pdf.vue文件,内容如下(注意我的路径,这个路径跟public的路径是一样的,前面加了一个/,原因如下:当我们利用npm run serve时,我们的本地电脑也会开启一个服务将public项目中的资源开发出来,此时跟服务器是一样的,你去访问:localhost:8080/pdf/web/viewer.html 是可以正常访问通的,这里不理解的话,就依葫芦画瓢吧,没关系的 ):
- <template>
- <iframe :src="'/pdf/web/viewer.html?file='+pdfUrl"></iframe>
- </template>
- <script>
- export default {
- name: 'Pdf',
- props: {
- pdfUrl: {
- type: String,
- default: ''
- }
- }
- }
- </script>
- <style scoped>
- iframe {
- /* width: 960px; */
- width: 1100px;
- max-width: 100%;
- height: 800px;
- margin-left: 50%;
- transform: translateX(-50%);
- }
- </style>
复制代码 d.在页面中导入利用:
- <template>
- <div class="home">
- <div>这下面是我用来预览pdf文件的</div>
- <pdf :pdfUrl="pdfUrl"></pdf>
- </div>
- </template>
- <script>
- import pdf from './pdf.vue';
- export default {
- name: 'HomeView',
- components:{
- pdf
- },
- data() {
- return {
- pdfUrl:'http://localhost:8080/怎么删除wps中最后的空白页.pdf'
- }
- },
- created(){
-
- },
- };
- </script>
复制代码 e.预览效果是这样子的
f.到源码中修改一下把打印和下载都去掉,这一步很简单,各人自己去弄了,也可以直接利用我的pdf文件,我这里都已经改好了。末了的效果如下:
4.难点处理
很大概率你在本地能跑通代码,但是到线上会出问题,大概会出现的问题我都罗列在下面了
a:线上404
线上404的话,阐明你线上的这个pdf的资源没有上传到线上,大概线上写的路径不对!好比你的ip为192.168.1.182。如果正常的话,你去访问192.168.1.182/pdf/web/viewer.html 是可以正常访问通的。如果都没有出现正常的这个页面,如下:
那么阐明你pdf文件资源没上传大概你写的路径不对。 1.查抄dist包内里是否有这个pdf文件(一般放在public文件夹的都会原封不动的打到dist包中,这里还是需要查抄下) 2.如果发现有的话,阐明没问题,那么你需要到服务器上看下有没有这个pdf文件上传上去了没有。如果有的话,那就是你写的路径不对,大概是后台没有开发这个静态资源文件夹。此时如果你不懂的话,你就跟后台说下你要去访问这个页面,应该要用什么路径去访问才气访问的到。正常来说 192.168.1.182/pdf/web/viewer.html是可以的,如果不可以,大概是要加什么路径,好比192.168.1.182/web/pdf/web/viewer.html这种。如果你是web/pdf/web/viewer.html才气访问的到,那么你就要在你的pdf.vue内里改下路径以对应生产环境
b:线上显示资源跨域
这里是很显着从浏览器面板能看到的。这个的处理,需要你和后台一起处理,首先你访问/pdf/web/viewer.html这个的地点和你访问的页面的地点是需要在一个域名下的(如果不在的话,需要后台处理,开放个别域名),第二点,就是/pdf/web/viewer.html?file='+pdfUrl" 这个pdfUrl的地点最好也是跟你的pdf的viewer.html在同一个域名下,相当于三个都在同一域名下,就不会有跨域问题了。如果后台说是静态资源都放到另一台主机上了,那么麻烦他让他做个资源映射,保证你的pdfUrl是跟你的pdf的viewer.html在同一个域名下的
5.demo地点
demo地点可下载自己看代码:https://github.com/rui-rui-an/viewpdf
参考文章:https://juejin.cn/post/7207078219215732794?searchId=2024060423581130C1D707D73A6338E3BA#heading-14
6.更新
关于下载(忘记写下载了)
html:
我这里用的是一个div,然后文件名作为用户下载的入口,点击就能去下载
- <div class="downpdf" href="#" v-if="is_download" @click="goDownload">{{ pdfname }}</div>
复制代码 方法1(直接下载):
- downloadPdf(pdfurl) {
- let fileName = this.pdfname
- let reg = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]+).)+([A-Za-z0-9-~\/])+$/
- if (!reg.test(pdfurl)) {
- throw new Error('传入参数不合法,不是标准的文件链接')
- } else {
- let xhr = new XMLHttpRequest()
- xhr.open('get', pdfurl, true)
- xhr.setRequestHeader('Content-Type', 'application/pdf')
- xhr.responseType = 'blob'
- let that = this
- xhr.onload = function () {
- if (this.status == 200) {
- //接受二进制文件流
- var blob = this.response
- that.downloadExportFile(blob, fileName)
- }
- }
- xhr.send()
- }
- },
- downloadExportFile(blob, tagFileName) {
- let downloadElement = document.createElement('a')
- let href = blob
- if (typeof blob == 'string') {
- downloadElement.target = '_blank'
- } else {
- href = window.URL.createObjectURL(blob) //创建下载的链接
- }
- downloadElement.href = href
- downloadElement.download = tagFileName
- //下载后文件名
- document.body.appendChild(downloadElement)
- downloadElement.click() //点击下载
- document.body.removeChild(downloadElement) //下载完成移除元素
- if (typeof blob != 'string') {
- window.URL.revokeObjectURL(href) //释放掉blob对象
- }
- },
复制代码 方法二(通过调自己的后端的下载api来下载,这里得问自己的后台,我这里就不贴代码了)
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |