381 字
2 分钟
PDF预览组件
<template>
  <div class="pdf-preview-dialog">
    <div class="button-panel">
      <el-button
        size="mini"
        @click="closeView"
      >
        返回
      </el-button>
      <el-button
        type="primary"
        size="mini"
        @click="download"
      >
        下载
      </el-button>
    </div>
    <div
      ref="pdfContentRef"
      v-infinite-scroll="handleScroll"
      :infinite-scroll-distance="8"
      :infinite-scroll-disabled="disabled"
      class="pdf-dialog-content"
    >
      <pdf
        v-for="i in currentPage"
        ref="pdf"
        :key="i"
        :page="i"
        class="pdf-box"
        :src="preViewFile.fileUrl"
        @progress="$event=>totalProgress=Math.floor($event*100)"
      />
      <div class="load-pdf-more" />
    </div>
    <el-progress
      v-show="totalProgress!==100&&totalProgress!==0"
      class="progress"
      type="circle"
      :width="70"
      color="#0079e7"
      :percentage="totalProgress"
    />
  </div>
</template>

<script>
import pdf from 'vue-pdf';
export default {
  name: 'PdfView',
  components: {
    pdf
  },
  props: {
 
    preViewFile: {
      type: Object,
      default: null
    }
  },
  data() {
    return {
      progress: [],
      totalProgress: 0,
      scale: 100,  //  开始的时候默认和容器一样大即宽高都是100%
      currentPage: 1, // pdf文件页码
      numPages: 0, // pdf文件总页数
      fileShow: true, //
    };
  },
  computed: {
    disabled() {
      return (this.totalProgress !== 100 && this.totalProgress !== 0) || this.currentPage === this.numPages;
    }
  },
  mounted() {
    this.pdfToImg();
  },
  methods: {
    handleScroll(e) {
      if(this.currentPage < this.numPages) {
        this.currentPage++;
      }
    },
    // 当一次性取多个页面时,处理文件加载进度
    handleProgress(i,value) {
      this.progress[i - 1] = value;
      if(!this.numPages) return this.totalProgress = 0;

      const total = _.sum(this.progress) / this.currentPage;
      this.totalProgress = Math.floor(total * 100);
    },
    pdfToImg() {
      if(!this.preViewFile.fileUrl) return;
      this.numPages = 0;
      this.currentPage = 1;
      // 计算pdf页码总数
      let loadingTask = pdf.createLoadingTask(this.preViewFile.fileUrl);
      if(!loadingTask || !loadingTask.promise) return;

      loadingTask.promise.then((pdfInfo)=>{
        this.numPages = pdfInfo.numPages;
      });
    },
    // 关闭返回
    closeView() {
      this.$emit('closeView');
    },
    // 下载文件
    download() {
      if(!this.preViewFile || !this.preViewFile.fileUrl) return;
        
      window.open(this.preViewFile.fileUrl, '_blank');
    },
  }
};
</script>

<style lang='less' scoped>
.pdf-preview-dialog {
    position: fixed;
    z-index:99;
    height: 100vh;
    padding-top: 72px;
    bottom: 0;
    left: 0;
    z-index: 99;
    width: 100%;
    background: #fff;
      .pdf-dialog-content {
        padding: 8px;
        width: 100%;
        height: calc(100vh - 100px);
        overflow-y: auto;
        .webkit-scrollbar(0,0);
        margin:0;
        padding:0;
        .pdf-box{
            width: 100%;
            height: 100%;
        }
        .load-pdf-more {
          height: 12px;
        }
      }
      /deep/.progress{
            position: absolute;
            left: 50%;
            top:50%;
            transform: translate(-50%);
        }
      .button-panel{
        padding: 0 20px;
        display: flex;
      }
      /deep/.el-button--mini{
        padding: 6px 10px;
      }
  }
  .file-preview{
      z-index: 99;
      position: fixed;
      left: 0;
      top: 60px;
      width:100vw;
      height: calc(100vh - 60px);
  }
  .file-btn-close{
      position: absolute;
      height: 60px;
      left: 0;
      top: 0;
      width: 100%;
      padding:0 10px;
      background: #323639;
      display: flex;
      align-items: center;
      gap:10px;
      [class^=el-icon]{
          padding: 4px;
          color: #fff;
          font-size: 20px;
          font-weight: bolder;
      }
  }
  
</style>
PDF预览组件
https://ping5-1.github.io/posts/vue/pdf预览/
作者
YiPing5
发布于
2023-03-05
许可协议
CC BY-NC-SA 4.0