您好,欢迎来到百家汽车网。
搜索
您的当前位置:首页vue中如何实现pdf文件预览的方法

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

来源:百家汽车网


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

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

想如下:

<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>

显示效果如下:

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

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

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

content-disposition :attachment; filename="DOC-20171013-WA0035.pdf"

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

https://www.gxlcms.com/article/1436.htm

过程如下:

  • 执行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就会显示下一页按钮;

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

    Copyright © 2019- baijiahaobaidu.com 版权所有 湘ICP备2023023988号-9

    违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

    本站由北京市万商天勤律师事务所王兴未律师提供法律服务