pdf预览功能

90 阅读1分钟

pdf预览功能

pdfjs-dist使用,如果安装报错,可能是版本不对,安装固定版本

"pdfjs-dist": "2.4.456",

代码如下:

<template>
    <div class>
        <div class="pdf-preview" ref="pdfPreview">
          <div ref="canvasCont" class="canvas-container">
            <canvas ref="myCanvas" class="pdf-container"></canvas>
          </div>
          <div class="pagination-wrapper">
            <el-button type="primary" @click="clickPre">上一页</el-button>
            <span style="margin:0 16px">第{{ pageNo }} / {{ pdfPageNumber }}页</span>
            <el-button type="primary" @click="clickNext">下一页</el-button>
          </div>
        </div>
    </div>
  </template>
  
  <script>
  const pdfJS = require("pdfjs-dist");
  pdfJS.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/build/pdf.worker.entry");
  export default {
    name:"PptPreview",
    data () {
      return {
        url:"",
        pageNo: null,
        pdfPageNumber: null,
        renderingPage: false,
        pdfData: null, // PDF的base64
        scale: 1, // 缩放值
        width: "",
        height: "",
      };
    },
 
    mounted () {
        this.url= this.$route.params.url
            this.loadPdfData()
       
    },
    activated(){
        this.url= this.$route.params.url
        this.loadPdfData() 
    },
    methods: {
      loadPdfData () {
        // 引入pdf.js的字体
        //读取base64的pdf流文件
        console.log("pdfJS",pdfJS,this.url);
        if(!this.url) return
        this.pdfData = pdfJS.getDocument(
          this.url
        );
        this.renderPage(1);
      },
  
      // 根据页码渲染相应的PDF
      renderPage (num) {
        const _t = this
        _t.renderingPage = true;
        _t.pdfData.promise.then((pdf) => {
  
          _t.pdfPageNumber = pdf.numPages;
  
          pdf.getPage(num).then((page) => {
            // 获取DOM中为预览PDF准备好的canvasDOM对象
            console.log("this.$refs", _t);
  
            let canvas = _t.$refs.myCanvas;
            let ctx = canvas.getContext("2d");
  
            // 获取页面比率
            let ratio = _t._getRatio(ctx);
  
            // 根据页面宽度和视口宽度的比率就是内容区的放大比率
            let dialogWidth = _t.$refs["canvasCont"].offsetWidth;
            let pageWidth = page.view[2] * ratio;
            let scale = dialogWidth / pageWidth;
            let viewport = page.getViewport({ scale });
  
  
            // 记录内容区宽高,后期添加水印时需要
            _t.width = viewport.width * ratio;
            _t.height = viewport.height * ratio;
  
            canvas.width = _t.width;
            canvas.height = _t.height;
  
            // 缩放比率
            ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
  
            let renderContext = {
              canvasContext: ctx,
              viewport: viewport,
            };
            page.render(renderContext).promise.then(() => {
              this.renderingPage = false;
              this.pageNo = num;
  
              // 添加水印
              // this._renderWatermark();
              console.log("?? _t.refs?", _t.$refs);
              
          _t.$refs.pdfPreview.scrollTo(0,0)
            });
          });
        });
      },
      // 计算角度
      _getRatio (ctx) {
        let dpr = window.devicePixelRatio || 1;
        let bsr =
          ctx.webkitBackingStorePixelRatio ||
          ctx.mozBackingStorePixelRatio ||
          ctx.msBackingStorePixelRatio ||
          ctx.oBackingStorePixelRatio ||
          ctx.backingStorePixelRatio ||
          1;
        return dpr / bsr;
      },
  
      // 在画布上渲染水印
      _renderWatermark () {
        let canvas = this.$refs.myCanvas;
        let ctx = canvas.getContext("2d");
        // 平铺水印
        let pattern = ctx.createPattern(this._initWatermark(), "repeat");
        ctx.rect(0, 0, this.width, this.height);
        ctx.fillStyle = pattern;
        ctx.fill();
      },
  
      // 生成水印图片
      _initWatermark () {
        let canvas = document.createElement("canvas");
        canvas.width = 200;
        canvas.height = 200;
        let ctx = canvas.getContext("2d");
        ctx.rotate((-18 * Math.PI) / 180);
        ctx.font = "10px Vedana";
        ctx.fillStyle = "rgba(0, 0, 0, 0.8)";
        ctx.textAlign = "left";
        ctx.textBaseline = "middle";
        return canvas;
      },
  
      clickPre () {
        if (!this.renderingPage && this.pageNo && this.pageNo > 1) {
          this.renderPage(this.pageNo - 1);
        }
      },
      clickNext () {
        if (
          !this.renderingPage &&
          this.pdfPageNumber &&
          this.pageNo &&
          this.pageNo < this.pdfPageNumber
        ) {
          this.renderPage(this.pageNo + 1);
        }
      },
    },
  };
  </script>
  
  <style scoped>
  .pdf-preview {
    display: flex;
    flex-direction: column;
    align-items: center;
    height: calc(100vh - 80px);
    overflow: scroll;
  }
  
  .canvas-container {
    width: 100%;
    position: relative;
    display: flex;
    justify-content: center;
  }
  
  .pdf-container {
    width: 100%;
    height: 100%;
  }
  
  .pagination-wrapper {
    display: flex;
    background: #fff;
    justify-content: center;
    align-items: center;
    padding: 20px;
    width: 100%;
  }
  </style>
​