欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

vue中如何实现pdf文件预览的方法

程序员文章站 2022-06-08 22:25:20
今天产品提出一个优化的需求,就是之前我们做的图片展示就是一个img标签搞定,由于我们做的是海外后台管理系统,那边的人上传的文件时pdf格式,vue本事是不支持这种格式文件展...

今天产品提出一个优化的需求,就是之前我们做的图片展示就是一个img标签搞定,由于我们做的是海外后台管理系统,那边的人上传的文件时pdf格式,vue本事是不支持这种格式文件展示的,于是就google搜索,发现有iframe、embed、vueshowpdf(测试了不咋好用)、pdf等,本文说一下pdf插件的使用过程。

说明:iframe标签这种,对于有的链接是可以的,比如这种链接在服务器端没有设置享有头content-disposition,就可以直接显示,如下:

vue中如何实现pdf文件预览的方法

想复制代码如下:

<iframe src="http://storage.xuetangx.com/public_assets/xuetangx/pdf/playerapi_v1.0.6.pdf" width="100%" height="100%">
 this browser does not support pdfs. please download the pdf to view it: <a href="/test.pdf" rel="external nofollow" >download pdf</a>
</iframe>

显示效果如下:

vue中如何实现pdf文件预览的方法

如果pdf有很多页,也不用考虑分页功能,自动可以向下滑动就翻页,看着挺好,但是,且往下继续看----->

我们把上边的链接换成' https://ecs7.tokopedia.net/instant-loan/file/29a2218e-bef9-44cb-b92b-8e81bc4d5228_doc-20171013-wa0035.pdf ',发现什么了?快看截图。。。同样是pdf链接,怎么这个就不行?

vue中如何实现pdf文件预览的方法

什么情况,下载框,必须下载才能看到,那多影响体验,下到本地还占我磁盘,不行不行,把上边那个连接放到浏览器,回车看一下响应头部:

content-disposition :attachment; filename="doc-20171013-wa0035.pdf"

就是它,让我们必须弹出下载框,由于这些文件是在远程服务器上存贮着,想着让后端看能不能检测到这个响应头,他们也懒得处理,后来只能自己处理了,鉴于这种情况,网上也是有很多解决办法的,本人试验过可以的。中间也是借用了一篇文章 ,根据自己需求,做了简单的处理。

过程如下:

  • 执行npm install pdf-dist --save
  • 在comments目录下创建两个文件:pdf.vue 和 index.js
< !--pdf.vue--><template >
 <div id = "container": class = "{'back': isshow}" >
 <canvas id = "the-canvas" > 
</canvas> 
 <!-- / / 添加关闭pdf功能-->
<span: class = "{'close':isshow}"@click = "closepdf" > close < /span> 
 <p class="foot" v-if="pdfdoc"> 
 <button class="left" @click="onprevpage" v-if="pagenum>1">上一页</button >
 <button class = "right"@click = "onnextpage"v -if = "pagenum<pdfdoc.numpages" > 下一页 < /button> 
 </p > 
</div>
 </template > 
<script >
 import pdfjs from 'pdfjs-dist'export
default {
 data() {
  return {
  isshow:
  false,
  //通过该属性动态添加类,让pdf显示或隐藏 
  pdfdoc: null,
  //可以打印发现是一个对象,里面有页数信息等 
  pagenum: 1,
  pagerendering: false,
  pagenumpending: null,
  scale: 0.9
  }
 },
 methods: {
  closepdf() {
  this.isshow = false
  },
  showpdf(url) {
  this.isshow = true let _this = this pdfjs.getdocument(url).then(function(pdf) {
   _this.pdfdoc = pdf

   _this.renderpage(1)
  })
  },
  renderpage(num) {
  this.pagerendering = true let _this = this this.pdfdoc.getpage(num).then(function(page) {
   var viewport = page.getviewport(_this.scale) let canvas = document.getelementbyid('the-canvas') canvas.height = viewport.height canvas.width = viewport.width // render pdf page into canvas context 
   var rendercontext = {
   canvascontext: canvas.getcontext('2d'),
   viewport: viewport
   }
   var rendertask = page.render(rendercontext) // wait for rendering to finish 
   rendertask.promise.then(function() {
   _this.pagerendering = false
   if (_this.pagenumpending !== null) {
    // new page rendering is pending 
    this.renderpage(_this.pagenumpending) _this.pagenumpending = null
   }
   })
  })
  },
  queuerenderpage(num) {
  if (this.pagerendering) {
   this.pagenumpending = num
  } else {
   this.renderpage(num)
  }
  },
  onprevpage() {
  if (this.pagenum <= 1) {
   return
  }
  this.pagenum--this.queuerenderpage(this.pagenum)
  },
  onnextpage() {
  if (this.pagenum >= this.pdfdoc.numpages) {
   return
  }
  this.pagenum++this.queuerenderpage(this.pagenum)
  }
 }
 } 
< /script>
<style scoped="" type="text/css ">
.back { 
background-color: rgba(0, 0, 0, 0.788); position:fixed; 
width: 100%; 
 height: 100%; 
top: 0; left: 0; 
 text-align: center; 
 padding: 20px; 
z-index: 100; 
 overflow: scroll;
}
.close{ 
 position: absolute; 
 right: 20px; 
 top: 20px; 
z-index: 200; 
color: #fff; 
cursor: pointer;
} 
.foot {
 position: absolute; 
bottom: 50px; 
left: 50%; 
 transform: translate(-50%,0);
}
</style>"
// index.js
import pdf from './pdf'
var $vmexport
default {
 install(vue, options) {
  if (!$vm) {
  const pdfplugin = vue.extend(pdf)
  $vm = new pdfplugin().$mount()
  document.body.appendchild($vm.$el)
  }
  vue.prototype.$showpdf = function(url) {
  $vm.showpdf(url)
  }
 }
 }

3. 在main.js中引入

import pdf from './components/pdf'
vue.use(pdf)

这样就可以全局使用了,使用的时候就直接使用,本文是在一个图片展示 的地方加上一个点击事件,点击时触发该函数即可;

function showpdf() {
 let url = 'http://storage.xuetangx.com/public_assets/xuetangx/pdf/playerapi_v1.0.6.pdf'
 // let url = 'https://ecs7.tokopedia.net/instant-loan/file/29a2218e-bef9-44cb-b92b-8e81bc4d5228_doc-20171013-wa0035.pdf' 
 this.$showpdf(url)
}

文中添加了关闭功能,点击close即可关闭pdf的展示, 同时组件中也有分页功能,如果页数大于1就会显示下一页按钮;

vue中如何实现pdf文件预览的方法

以上既是本人实现的过程,至于跨域问题,我这边还没遇到,现在是本地访问可以的,等到线上再看看行不行,如果不行后边再追加方法实现。希望对大家的学习有所帮助,也希望大家多多支持。