admin管理员组

文章数量:1648973

用element ui的dialog组件,在弹出框中预览pdf文件

效果图

安装vue-pdf

        yarn add vue-pdf

pdf预览组件

子组件


<template>
  <div class="pdf">
    <div class="show">
      <pdf
        ref="pdf"
        :rotate="pageRotate"
        :src="src"
        :page="pageNum"
        style="display: inline-block; width: 100%"
      ></pdf>
    </div>
    <div class="pdf_footer">
      <div class="info">
        <div>当前页数/总页数:{{ pageNum }}/{{ numPages }}</div>
      </div>
      <div class="operate">
        <div class="btn" @click.stop="clock">顺时针</div>
        <div class="btn" @click.stop="counterClock">逆时针</div>
        <div class="btn" @click.stop="prePage">上一页</div>
        <div class="btn" @click.stop="nextPage">下一页</div>
        <div class="btn" @click="scaleD">放大</div>
        <div class="btn" @click="scaleX">缩小</div>
        <div class="btn" @click="fileDownload(fileSrc, 'pdf文件')">下载</div>
      </div>
    </div>
  </div>
</template>
<script>
import pdf from "vue-pdf";
export default {
  name: "AppPdf",
  components: {
    pdf,
  },
  props: {
    fileSrc: {
      type: String,
      require: true,
      default: "",
    },
  },
  data() {
    return {
      src: "",
      numPages: undefined,
      pageNum: 1,
      // 加载进度
      loadedRatio: 0,
      // 页面加载完成
      curPageNum: 0,
      // 放大系数 默认百分百
      scale: 100,
      // 旋转角度 ‘90’的倍数才有效
      pageRotate: 0,
    };
  },
  mounted() {
    this.loadUPDf(this.fileSrc);
  },

  methods: {
    loadUPDf(url) {
      console.log(url);
      this.src = pdf.createLoadingTask(url);
      this.src.promise.then((pdf) => {
        this.numPages = pdf.numPages; //获取pdf页数
      });
    },
    //下载PDF
    fileDownload(data, fileName) {
      window.location.href = data;
    },
    //放大
    scaleD() {
      this.scale += 5;
      this.$refs.pdf.$el.style.width = parseInt(this.scale) + "%";
    },

    //缩小
    scaleX() {
      // scale 是百分百展示 不建议缩放
      // if (this.scale == 100) {
      //   return;
      // }
      this.scale += -5;
      console.log(parseInt(this.scale) + "%");
      this.$refs.pdf.$el.style.width = parseInt(this.scale) + "%";
    },
    // 切换上一页
    prePage() {
      var p = this.pageNum;
      p = p > 1 ? p - 1 : this.numPages;
      this.pageNum = p;
    },
    // 切换下一页
    nextPage() {
      var p = this.pageNum;
      p = p < this.numPages ? p + 1 : 1;
      this.pageNum = p;
    },
    // 顺时针选中角度
    clock() {
      this.pageRotate += 90;
    },
    // 逆时针旋转角度
    counterClock() {
      this.pageRotate -= 90;
    },
    //很重要,父组件关闭前,清空子组件的值,不然第二次预览打开空白
    resetPageNum() {
      this.numPages = undefined;
    },
  },
};
</script>
<style lang="scss" scoped>
.pdf {
  .show {
    overflow: auto;
    margin: auto;
    max-width: 75%;
    height: 80vh;
    max-height: 690px;
  }
}
.pdf_footer {
  position: sticky;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 10px 0;
  background-color: rgba(255, 255, 255, 0.5);
  .info {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    div {
      width: 30%;
    }
  }
  .operate {
    margin: 10px 0 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    div {
      // width: 80px;
      text-align: center;
      font-size: 15px;
    }
    .btn {
      cursor: pointer;
      margin: 5px 10px;
      width: 120px;
      border-radius: 10px;
      padding: 5px;
      color: #fff;
      background-color: #3dcbbc;
    }
  }
}
</style>

 父组件

 <el-dialog
      ref="elDialog"
      :visible.sync="dialogVisible"
      title="PDF预览"
      width="80%"
      @close="closedialog"
      :close-on-click-modal="false"
      append-to-body
      v-if="destroy"
    >
      <div style="height: calc(90vh - 160px); overflow-y: auto">
        <FilePreview ref="mypdf" :fileSrc="fileCont"></FilePreview>
      </div>
    </el-dialog>

 点击预览,将pdf流传入给子组件。

this.destroy = true;
this.fileCont = "http://192.168.5.122:19002" + file.url;
this.dialogVisible = true;

关闭预览

 closedialog() {
      this.destroy = false;
      this.dialogVisible = false;
      this.$refs.mypdf.resetPageNum();
    },

扩展

根据接口判断文件类型

getFileType (url) {
      let pdfReg = /^.+(\.pdf)$/
      let txtReg = /^.+(\.txt)$/
      let wordReg = /^.+(\.doc|\.docx)$/
      let excelReg = /^.+(\.xls|\.xlsx)$/
      let jpgReg = /^.+(\.png|\.jpg|\.jpeg|\.bmp)$/
      if (pdfReg.test(url)) {
        return 'pdf'
      }
      if (txtReg.test(url)) {
        return 'txt'
      }
      if (wordReg.test(url)) {
        return 'word'
      }
      if (excelReg.test(url)) {
        return 'excel'
      }
      if (jpgReg.test(url)) {
        return 'picture'
      }
    }

注意

         实现pdf预览的方式有多种,可先将后端返回的pdf流输入到浏览器地址栏中,进行测试,若能直接预览到pdf文件或者下载,则可通过vue-pdf的方式在前端进行预览。

        使用此方法时,还需注意pdf流的地址是否正确,以及是否跨域。

本文标签: 文件vuePDF