Vue PDF文件预览vue-pdf

   最近作项目,遇到预览PDF这个功能,在网上找了找,大多推荐的是pdf.js,不过在Vue中仍是想偷懒直接npm组件,最后找到了一个还不错的Vue-pdf 组件,GitHub地址:https://github.com/FranckFreiburger/vue-pdf#readme
不过通常GitHub上的注释比较简洁,因此这里把本身实际使用的过程总结了一下,下面贴代码
 
 本博客源码:  https://github.com/shengbid/vue-demo  这个项目里会把平时博客写的一些功能的代码都放在里面,有须要能够下载看看,有帮助的话点个star哈
 
引用: npm install --save vue-pdf
 
template代码:
<template>
  <div class="pdf" v-show="fileType === 'pdf'">
    <p class="arrow">
    // 上一页
    <span @click="changePdfPage(0)" class="turn" :class="{grey: currentPage==1}">Preview</span>
    {{currentPage}} / {{pageCount}} // 下一页
    <span @click="changePdfPage(1)" class="turn" :class="{grey: currentPage==pageCount}">Next</span>
    </p>
    // 本身引入就能够使用,这里个人需求是作了分页功能,若是不须要分页功能,只要src就能够了
    <pdf :src="src" // src须要展现的PDF地址
      :page="currentPage" // 当前展现的PDF页码
      @num-pages="pageCount=$event" // PDF文件总页码
      @page-loaded="currentPage=$event" // 一开始加载的页面
      @loaded="loadPdfHandler"> // 加载事件
    </pdf>
  </div>
</template>
js代码:<script>   // 引入PDF
 import pdf from 'vue-pdf' export default { components: {pdf}, data () { return { currentPage: 0, // pdf文件页码 pageCount: 0, // pdf文件总页数 fileType: 'pdf', // 文件类型
     src: '', // pdf文件地址

} },
  created: {
    // 有时PDF文件地址会出现跨域的状况,这里最好处理一下
    this.src = pdf.


createLoadingTask(this.src)
  } method: { // 改变PDF页码,val传过来区分上一页下一页的值,0上一页,1下一页
 changePdfPage (val) { // console.log(val)
        if (val === 0 && this.currentPage > 1) { this.currentPage--
          // console.log(this.currentPage)
 } if (val === 1 && this.currentPage < this.pageCount) { this.currentPage++
          // console.log(this.currentPage)
 } }, // pdf加载时
 loadPdfHandler (e) { this.currentPage = 1 // 加载的时候先加载第一页
 } } } </script>

实际效果html

 

问题补充:  文件打印乱码问题解决方法

以前有人问了关于PDF打印乱码问题,我本身试了确实有这个问题,在官网找了一下,有人提交了代码解决了这个问题,如今我把方法附上vue

原始的打印页面,PDF格式乱码,主要是由于PDF里使用了自定义字体,不能识别git

 

须要修改vue-pdf安装包的pdfjsWrapper.js文件github

上面后缀为1的文件是原始的,红线框起来的是我修改以后的文件npm

替换以后,打印就能正常显示了,canvas

 

 

博客园貌似不能上传文件,代码太多就不放上来了,若是有须要能够找我邮箱发你,或者到官网本身修改文件跨域

git-hup地址:https://github.com/FranckFreiburger/vue-pdf/pull/130/commits/253f6186ff0676abf9277786087dda8d95dd8ea7,promise

 

 上面提供的解决文件打印乱码的问题,实现起来比较麻烦,并且如今vue-pdf的版本已经更新了,用这个方法可能还会出现空白页的问题.本身在研究了下,用了iframe来预览打印,效果会更好些,这里把方法放上来,有须要的能够试试浏览器

这里的例子是把PDF文件放在elment的弹框中,固然你能够根据你本身的适用场景来决定安全

html:

<el-dialog :close-on-click-modal="false" :visible.sync="dialogVisible" :fullscreen="true" title="文件预览">
          <div class="agreement_picture">
            <div class="pdf">
              <!-- <pdf // 以前的用PDF插件的方法
                v-for="i in pdf.numPages" :key="i" :page="i" :src="src">
              </pdf> -->
              // 使用iframe方法
              <iframe :src="src" frameborder="0" style="width: 100%; height: 100%"></iframe>
            </div>
          </div>
          <span slot="footer" class="dialog-footer">
            <div class="tip-left transfer">
                <el-button type="info" @click="dialogVisible=false">不一样意</el-button>
              <el-button type="danger" @click="agreeSignFun">赞成</el-button>
            </div>
          </span>
        </el-dialog>

js:

 data () { return { src: '/static/file/中国互联网总体网民发展情况——《第31次中国互联网发展情况调查报告(上)》.pdf', //pdf地址,这里我用的是我本地的文件,你也能够使用后台的文件
 dialogVisible: true } }

 

效果展现:

打印效果:

 

补充内容:

朋友们,关于跨域问题,我这里说明一下,若是你是在本地localhost环境请求后台接口返回的文件地址,通常都会跨域,报错以下

这个文件地址我在浏览器能够直接打开预览

 

遇到这种问题,是由于你本地的localhost和你后台返回的域名不一致,能够先用一个本地静态文件调试效果,在线上环境即经过打包部署的环境(域名和返回的PDF域名一致的环境)再看效果.若是域名端口一致的状况还有报跨域的错误,那你的项目与vue-pdf八字不合,建议更换组件

 

另外补充一下打印的问题,经过vue-pdf自带的打印功能,打印出来的效果通常是这样

 

这个做者在git上也说了,如今vue-pdf的打印功能还在试验阶段,没有完善,因此寄但愿于这个方法实现打印还需一段时日,上面的内容里我用了<iframe>标签来预览打印,可是如今iframe已经不怎么使用了,有些项目还不容许用,这里我再补充两种打印方法

1. 先把PDF内容转成图片后再打印

<el-dialog title="文件预览" :visible.sync="dialogVisible" width="50%"
    >
      <div ref="printContent">
        <!-- 加载所有页面的PDF是循环生成,不能指定ref,不能调用print打印方法 -->
        <Pdf v-for="i in numPages" :key="i" :src="src" :page="i"
        />
        <!-- 写一个隐藏的PDF,用来调用打印 -->
        <Pdf v-show="false" ref="printPdf" :src="src"
        />
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="print">vue-pdf自带打印</el-button>
        <el-button type="primary" @click="toImg">转图片打印</el-button>
      </span>
    </el-dialog>
<script> import Pdf from 'vue-pdf' import html2canvas from 'html2canvas' import printJS from 'print-js' export default { components: { Pdf }, data() { return { fileList: [ { id: 1, fileName: '增进函', fileUrl: 'http://172.16.79.33:8888/group1/.........../rBBPIV7whg2AQNCmAAoc6DKtkwE841.pdf' }, { id: 2, fileName: '应收帐款', fileUrl: `${window.location.origin}/test1.pdf`
 } ], numPages: undefined, dialogVisible: false, src: '', printName: '转图片打印' } }, created() { }, methods: { // 预览
 preview(item) { this.src = Pdf.createLoadingTask(item.fileUrl) this.src.promise.then(pdf => { this.numPages = pdf.numPages }) this.dialogVisible = true
      this.printName = item.fileName }, // 转图片打印
 toImg() {  html2canvas(this.$refs.printContent, { backgroundColor: null, useCORS: true, windowHeight: document.body.scrollHeight }).then((canvas) => { const url = canvas.toDataURL() printJS({ printable: url, type: 'image', documentTitle: this.printName }) // console.log(url)
 }) }, // pdf自带打印
 print() { this.$refs.printPdf.print() } } }

打印效果

 

2.跳转页面打印,这种和iframe的差很少,新建一个页面,调用window.print()打印页面,效果以下

 

最近我会把vue-pdf的使用整理一下,把源码放到git上,以前的代码找不到了

 若是以上都不能解决你的问题,我以为你能够使用window.open()直接新页面打开预览,使用浏览器自带的打印预览功能.若是产品不一样意,你能够对他晓之以情,动之以理

 

如今通常项目为了安全性,不会直接返回文件地址,会返回文件流的格式,对于文件流格式文件能够转化成blob文件,若是有须要能够看下我另外一篇博客:文件流数据如何转blob文件 https://www.cnblogs.com/steamed-twisted-roll/p/11821148.html

相关文章
相关标签/搜索