vue使用vue-pdf预览pdf文件,带有换页、缩放、选择功能

1.安装

npm install --save vue-pdf

2.在需要用的页面引入 

import pdf from 'vue-pdf'

 3.带有放大、缩小、换页功能的用例

<template>
  <div class="page-container">
    <div class="main">
      <pdf
      :src="src"
      :page="currentPage"
      @progress="loadedRatio = $event"
      @loaded="loadPdfHandler"
      @num-pages="pageCount=$event"
      @page-loaded="currentPage=$event"
      ref="wrapper"
      class="pdf"></pdf>
    </div>
    <ul class="footers">
      <li :class="{select:idx==0}" @touchstart="idx=0" @touchend="idx=-1" @click="scaleD">
        <p class="more-p">放大</p>
      </li>
      <li :class="{select:idx==1}" @touchstart="idx=1" @touchend="idx=-1" @click="scaleX">
        <p class="small-p">缩小</p>
      </li>
      <li :class="{select:idx==2}" @touchstart="idx=2" @touchend="idx=-1" @click="changePdfPage(0)">
        <p class="up-p">上一页</p>
      </li>
      <li :class="{select:idx==3}" @touchstart="idx=3" @touchend="idx=-1" @click="changePdfPage(1)">
        <p class="down-p">下一页</p>
      </li>
      <li>
        <p>当前第{{ currentPage }}页/共{{ pageCount }}页</p>
      </li>
    </ul>
  </div>

</template>

<script>
import pdf from 'vue-pdf'
export default {
  data() {
    return {
      currentPage: 1, // 当前页码
      pageCount: 0, // 总页码
      scale: 100,
      idx: -1,
      loadedRatio: 0,
      src: 'https://dakaname.oss-cn-hangzhou.aliyuncs.com/file/2018-12-28/1546003237411.pdf'
    }
  },
  created() {
    this.src = pdf.createLoadingTask(this.src) // 处理一下跨域
  },
  components: {
    pdf
  },
  methods: {
    // 改变PDF页码,val传过来区分上一页下一页的值,0上一页,1下一页
    changePdfPage(val) {
      if(val === 0 && this.currentPage > 1) {
        this.currentPage--;
      }
      if(val === 1 && this.currentPage < this.pageCount) {
        this.currentPage++;
      }
      console.log(this.currentPage);
      console.log(this.pageCount);
    },
    goBack() {
      this.$router.go(-1);
    },
    // pdf加载时
    loadPdfHandler(e) {
      this.currentPage = 1; // 加载的时候先加载第一页
    },
    //放大
    scaleD() {
      this.scale += 5;
      this.$refs.wrapper.$el.style.width = parseInt(this.scale) + "%";
    },

    //缩小
    scaleX() {
      if(this.scale == 100) {
        return;
      }
      this.scale += -5;
      this.$refs.wrapper.$el.style.width = parseInt(this.scale) + "%";
    }
  }
}
</script>

<style scoped>
.main {
  overflow: hidden;
}
.footers {
  position: fixed;
  bottom: 0;
  width: 100%;
  display: flex;
  z-index: 100;
  color: #333;
  border-top: 1px solid #f0f0f0;
  line-height: 10px;
  height: 30px;
}
.li {
  text-align: center;
  flex: 1;
  padding: 5px;
  cursor: pointer;
}
.ul {
  list-style: none;
}
.more-p {
  border-right: 1px solid #f0f0f0;
  margin-right: 40px;
  cursor: pointer;
}
.small-p {
  margin-right: 40px;
  cursor: pointer;
}
.up-p {
  margin-right: 40px;
  cursor: pointer;
}
.down-p {
  border-radius: 0 none;
  cursor: pointer;
  margin-right: 50px;
}
</style>

效果

4.pdf不显示签名和红章 

1.打开node_modules 文件夹下面的pdfjs-dist -> build -> pdf.worker.js

2.搜索data.fieldType,将if里面这句注释掉就可以

效果

**但是有个问题,这样配置后,显示有签章的页面就会报错Uncaught (in promise) DOMException: Failed to execute 'postMessage' on 'DedicatedWorkerGlobalScope': #<Promise> could not be cloned. 目前还未解决

4.笔记 

1.src是pdf文件的路径,可以是相对地址、绝对地址、网址

2.:page当前pdf显示的页码,默认是1

3.@progress是pdf页面的加载进度(这个不是很懂)

4.@loaded  pdf加载的时候执行

5.@num-page监听pdf的加载,获取pdf总页数

6.@page-loaded是pdf加载成功的回调(应该是范围换页后的页码)

5.在对话框显示pdf,并且带有选择功能

效果:

代码:

<template>
  <div class="page-container">
    <el-button @click="pdfDlgVisible = true">点击看看</el-button>
    <el-dialog :visible.sync="pdfDlgVisible" title="pdf预览" height="calc(100vh - 10px)" class="pdf-dialog">
      <div class="main">
      <pdf
      :src="src"
      :page="currentPage"
      @progress="loadedRatio = $event"
      @loaded="loadPdfHandler"
      @num-pages="pageCount=$event"
      @page-loaded="currentPage=$event"
      ref="wrapper"
      class="pdf"></pdf>
      </div>
      <div slot="footer" class="footers">
        <ul class="footer-ul">
          <li>
            <el-checkbox v-model="checkPage[currentPage]" class="radio-class" @change="checkClick(currentPage)">选择</el-checkbox>
          </li>
          <li :class="{select:idx==0}" @touchstart="idx=0" @touchend="idx=-1" @click="scaleD">
            <p class="more-p">放大</p>
          </li>
          <li :class="{select:idx==1}" @touchstart="idx=1" @touchend="idx=-1" @click="scaleX">
            <p class="small-p">缩小</p>
          </li>
          <li :class="{select:idx==2}" @touchstart="idx=2" @touchend="idx=-1" @click="changePdfPage(0)">
            <p class="up-p">上一页</p>
          </li>
          <li :class="{select:idx==3}" @touchstart="idx=3" @touchend="idx=-1" @click="changePdfPage(1)">
            <p class="down-p">下一页</p>
          </li>
          <li>
            <p>当前第{{ currentPage }}页/共{{ pageCount }}页</p>
          </li>
        </ul>
        <el-button @click="pdfDlgVisible = false">取消</el-button>
        <el-button @click="commmit">确定</el-button>
      </div>
    </el-dialog>
  </div>
 
</template>
 
<script>
import pdf from 'vue-pdf'
export default {
  data() {
    return {
      currentPage: 1, // 当前页码
      pageCount: 0, // 总页码
      scale: 100,
      idx: -1,
      loadedRatio: 0,
      src: 'https://dakaname.oss-cn-hangzhou.aliyuncs.com/file/2018-12-28/1546003237411.pdf',
      pdfDlgVisible: false,
      checkPage: [],
      checkPageList: []
    }
  },
  mounted() {
  },
  created() {
    this.src = pdf.createLoadingTask(this.src) // 处理一下跨域
  },
  components: {
    pdf
  },
  methods: {
    // 改变PDF页码,val传过来区分上一页下一页的值,0上一页,1下一页
    changePdfPage(val) {
      if(val === 0 && this.currentPage > 1) {
        this.currentPage--;
      }
      if(val === 1 && this.currentPage < this.pageCount) {
        this.currentPage++;
      }
      for (let i=0; i<this.checkPageList.length; i++) {
        let data = this.checkPageList[i]
        if (data.page === this.currentPage) {
          this.checkPage[this.currentPage] = data.check
          break
        } else {
          this.checkPage[this.currentPage] = false
        }
      }
    },
    // pdf加载时
    loadPdfHandler(e) {
      this.currentPage = 1; // 加载的时候先加载第一页
    },
    //放大
    scaleD() {
      this.scale += 5;
      this.$refs.wrapper.$el.style.width = parseInt(this.scale) + "%";
    },
 
    //缩小
    scaleX() {
      if(this.scale == 100) {
        return;
      }
      this.scale += -5;
      this.$refs.wrapper.$el.style.width = parseInt(this.scale) + "%";
    },
    checkClick: function(data) {
      if (this.checkPageList.length === 0) {
        this.checkPageList.push({
          page: data,
          check: this.checkPage[data]
        })
      } else {
        for (let i=0; i<this.checkPageList.length; i++) {
          if (this.checkPageList[i].page === data) {
            this.checkPageList[i].check = this.checkPage[data]
            break
          } else {
            this.checkPageList.push({
              page: data,
              check: this.checkPage[data]
            })
            break
          }
        }
      }
      for (let i=0; i<this.checkPageList.length; i++) {
        let data1 = this.checkPageList[i]
        for (let j=i + 1; j<this.checkPageList.length; j++) {
          let data2 = this.checkPageList[j]
          if (data1.page === data2.page) {
            this.checkPageList.splice(i, 1)
          }
        }
      }
    },
    commmit: function() {
      console.log(this.checkPageList);
    }
  }
}
</script>
 
<style scoped>
.main {
  overflow: hidden;
}
.li {
  text-align: center;
  flex: 1;
  padding: 5px;
  cursor: pointer;
}
.footer-ul {
  bottom: 0;
  display: flex;
  /* margin-left: 20px; */
  margin: 0px;
  z-index: 200;
  list-style: none;
}
.more-p {
  border-right: 1px solid #f0f0f0;
  margin-right: 40px;
  cursor: pointer;
}
.small-p {
  margin-right: 40px;
  cursor: pointer;
}
.up-p {
  margin-right: 40px;
  cursor: pointer;
}
.down-p {
  border-radius: 0 none;
  cursor: pointer;
  margin-right: 50px;
}
</style>
<style>
.pdf-dialog .el-dialog__body {
  height: calc(100vh - 450px);
  overflow: auto;
  padding: 0px;
}
.pdf-dialog .el-dialog__header {
  overflow: auto;
  padding: 10px 0px 2px 20px;
}
.radio-class .el-checkbox__inner {
  height: 20px;
  width: 20px;
}
.radio-class .el-checkbox__label  {
  font-size: 25px;
}
</style>

 

posted @ 2020-01-17 15:24  努力加油进步  阅读(6888)  评论(0)    收藏  举报