vue预览pdf

149 阅读1分钟

vue-pdf插件(在同一页面切换显示时,渲染会有问题)

  1. npm install --save vue-pdf
  2. 封装组件
<template>
  <div>
    <div>
      <el-button @click="zoomIn">+</el-button>
      <el-button @click="zoomOut">-</el-button>
    </div>
    <pdf :src="src" v-for="i in numPages" :key="i" :page="i" style="width: 100%;"></pdf>
  </div>
</template>
<script>
  import pdf from 'vue-pdf'
  export default{
    name:'pdfItem',
    props:{
      pdfSrc:{
        type:String
      }
    },
    components:{
      pdf
    },
    data(){
      return {
        src:'',
        numPages:1,
        scale:100
      }
    },
    created(){
      this.getPdfUrl()
    },
    methods:{
      getPdfUrl() {
        let _this = this
        this.src = pdf.createLoadingTask(this.pdfSrc)
        this.src.promise.then(pdf => {
          _this.numPages = pdf.numPages
        }).catch((err) => {
          console.error('pdf加载失败',err)
        })

      },
      //放大
      zoomIn(){
        this.scale += 5
        this.$refs.pdf.map(item=>item.$el.style.width = parseInt(this.sacle) + '%')
      },
      //缩小
      zoomOut(){
        if(this.scale === 100){
          return
        }
        this.scale -= 5
        this.$refs.pdf.map(item=>item.$el.style.width = parseInt(this.scale) + '%')
      },
    }
  }
</script>

pdfjs-dist插件

  1. npm install pdfjs-dist
  2. 封装组件
<template>
  <!-- 分页显示开始 -->
  <!-- <div class="cpdf" id="cpdf">
    <div>
      <div class="pdf-controller">
        <el-button size="mini" @click="prev">上一页</el-button>
        <el-button size="mini" @click="next">下一页</el-button>
        <span class="pdf-page">Page: <span v-text="page_num"></span> / 
        <span v-text="totalPage"></span></span>
        <el-button class="pdf-plus" icon="el-icon-zoom-in" size="mini" @click="addscale" ></el-button>
        <el-button class="pdf-minus" icon="el-icon-zoom-out" size="mini" @click="minus" ></el-button>
      </div>
      <el-scrollbar style="max-height: 600px;overflow: scroll;">
  	<canvas class="canvasstyle" id="the-canvas"></canvas>
      </el-scrollbar>
    </div>
  </div> -->
  <!-- 分页显示结束 -->
  <!-- ------------------------------------------分割线----------------------------------------------- -->
  <!-- 全部显示开始 -->
  <div class="pdf-container">
    <div class="pdf-controller">
      <el-button size="mini" class="pdf-plus" icon="el-icon-zoom-in" @click="plus_btn"></el-button>
      <el-button size="mini" class="pdf-minus" icon="el-icon-zoom-out" @click="minus_btn"></el-button>
    </div>
    <el-scrollbar style="max-height: 600px;overflow-y: scroll;">
      <canvas v-for="index in totalPage" :key="index" :id="`canvas-${index}`"></canvas>
    </el-scrollbar>
  </div>
  <!-- 全部显示结束 -->
</template>
<script>
  import PDFJS from 'pdfjs-dist'
  const workerSrc = require('pdfjs-dist/build/pdf.worker.min.js')
  export default {
    name: 'new-pdf-item',
    props: ['pdfurl'],
    data() {
      return {
        pdfDoc: null, //pdfjs 生成的对象
        pageNum: 1,//
        pageRendering: false,
        pageNumPending: null,
        scale: 1,//放大倍数
        page_num: 0,//当前页数
        maxscale: 50,//最大放大倍数
        minscale: 1,//最小放大倍数
        totalPage:0,//总页数
      }
    },
    methods: {
      //渲染单个pdf
      renderPage(num) {
        console.log('scale',this.scale)
        let vm = this;
        this.pageRendering = true;
        // Using promise to fetch the page
        this.pdfDoc.getPage(num).then(pdfPage => {
          let viewport = pdfPage.getViewport(vm.scale);
          let canvas = document.getElementById('the-canvas')
          //alert(vm.canvas.height)
          canvas.width = viewport.width;
          canvas.height = viewport.height;
          let ctx = canvas.getContext('2d')
          let renderContext = {
            canvasContext: ctx,
            viewport: viewport
          };
          let renderTask = pdfPage.render(renderContext);
          // Wait for rendering to finish
          renderTask.promise.then(function() {
            vm.pageRendering = false;
            if(vm.pageNumPending !== null) {
              // New page rendering is pending
              vm.renderPage(vm.pageNumPending);
              vm.pageNumPending = null;
            }
          });
        });
        vm.page_num = vm.pageNum;
      },
      //单页放大
      addscale() {
        if(this.scale >= this.maxscale) {
          return
        }
        this.scale += 1;
        this.queueRenderPage(this.pageNum)
      },
      //单页缩小
      minus() {
        if(this.scale <= this.minscale) {
          return
        }
        this.scale -= 1;
        this.queueRenderPage(this.pageNum)
      },
      //上一页
      prev() {
        let vm = this
        if(vm.pageNum <= 1) {
          return;
        }
        vm.pageNum--;
        vm.queueRenderPage(vm.pageNum);
      },
      //下一页
      next() {
        let vm = this;
        if(vm.pageNum >= vm.totalPage) {
          return;
        }
        vm.pageNum++;
        vm.queueRenderPage(vm.pageNum);
      },
      queueRenderPage(num) {
        if(this.pageRendering) {
          this.pageNumPending = num;
        } else {
          this.renderPage(num);
        }
      },
      //渲染全部pdf
      loadPage(){
        console.log('scale',this.scale)
        let pdfDocument = this.pdfDoc
        for (let i = 1; i <= pdfDocument.numPages; i++) {
          pdfDocument.getPage(i).then(pdfPage => {
            let viewport = pdfPage.getViewport(this.scale)
            let canvas = document.getElementById(`canvas-${i}`)
            canvas.width = viewport.width
            canvas.height = viewport.height
            let ctx = canvas.getContext('2d')
            let renderTask = pdfPage.render({
              canvasContext: ctx,
              viewport: viewport
            })
            return renderTask.promise
          })
        }
      },
      //放大所有的pdf
      plus_btn(){
        if(this.scale >= this.maxscale) {
          return
        }
        this.scale += 0.2;
        this.loadPage()
      },
      //缩小所有的pdf
      minus_btn(){
        if(this.scale <= this.minscale){
          return;
        }
        this.scale -= 0.2;
        this.loadPage()
      },
    },
    computed: {

    },
    mounted() {
      //初始化
      PDFJS.GlobalWorkerOptions.workerSrc = workerSrc
      //this.pdfurl pdf地址,如果是流需单独处理一下
      PDFJS.getDocument(this.pdfurl).promise.then(pdfDocument => {
        this.pdfDoc = pdfDocument
        this.totalPage = pdfDocument.numPages // 页码
        this.loadPage()//加载全部pdf
        // this.renderPage(this.pageNum)//加载单个pdf
      }).catch(reason => console.error('PDF加载失败'))
    }
  }
</script>
<style lang="scss" scoped>
    .canvasstyle{
        width: 100%;
        height:100%;
    }
    .cpdf{
	color:#fff
    }
    .pdf-controller{
	margin: 10px 0;
	// text-align: center;
    }
    .pdf-plus,.pdf-minus{
	font-size: 14px;
    }
    .pdf-page{
	padding: 0 10px;
    }
</style>