使用vue-pdf实现pdf文件的预览、下载、打印功能。

287 阅读1分钟

1. 安装依赖

需要webpack 是4版本

不然会报错 

MainTemplate.hooks.hotBootstrap .....

npm i vue-pdf vue-pdf-signature

2. pdf 预览弹框

PdfDialog.vue

<template>  <div>    <el-dialog :title='title' :visible='visible' width='900px' @before-close='handleClose' ref='dialog'>      <div class='dialog-container'>        <div class="tools">          <el-button type="text" @click="FirstPage()">            <el-tooltip class="item" effect="light" content="第一页" placement="top"><i class="el-icon-d-arrow-left"></i>            </el-tooltip>          </el-button>          <el-button type="text" @click="changePdfPage(0)">            <el-tooltip class="item" effect="light" content="上一页" placement="top"><i class="el-icon-arrow-left"></i>            </el-tooltip>          </el-button>          <el-button type="text" @click="changePdfPage(1)">            <el-tooltip class="item" effect="light" content="下一页" placement="top"><i class="el-icon-arrow-right"></i>            </el-tooltip>          </el-button>          <el-button type="text" @click="lastPage()">            <el-tooltip class="item" effect="light" content="最后一页" placement=" top"><i                class="el-icon-d-arrow-right"></i>            </el-tooltip>          </el-button>          <el-button type="text" @click="setIsExit()" v-show="!isExit" style="margin-right:10px">            <el-tooltip class="item" effect="light" content="页码选择" placement="top"><i class="el-icon-setting"></i>            </el-tooltip>          </el-button>          <el-tooltip class="item" effect="light" content="页码选择" placement="top" v-show="isExit">            <el-select v-model="value" placeholder="请选择" @change="pageSelect" size="mini">              <el-option v-for="item in pageCount " :key="item" :label="'第' + item + '页'" :value="item">              </el-option>            </el-select>          </el-tooltip>          <el-button type="text" @click="scaleD()">            <el-tooltip class="item" effect="light" content="放大" placement="top"><i class="el-icon-zoom-in"></i>            </el-tooltip>          </el-button>          <el-button type="text" @click="scalex()">            <el-tooltip class="item" effect="light" content="缩小" placement="top"><i class="el-icon-zoom-out"></i>            </el-tooltip>          </el-button>          <el-button type="text" @click="clock()">            <el-tooltip class="item" effect="light" content="顺时针旋转" placement="top"><i                class="el-icon-refresh-right"></i>            </el-tooltip>          </el-button>          <el-button type="text" @click="counterclock()">            <el-tooltip class="item" effect="light" content="逆时针旋转" placement="top"><i class="el-icon-refresh-left"></i>            </el-tooltip>          </el-button>          <el-button type="text" @click="downPDF">            <el-tooltip class="item" effect="light" content="下载pdf" placement="top"><i class="el-icon-download"></i>            </el-tooltip>          </el-button>          <el-button type="text" @click="printPDF">            <el-tooltip class="item" effect="light" content="打印pdf" placement="top"><i class="el-icon-printer"></i>            </el-tooltip>          </el-button>          <p class="total">            <el-tooltip class="item" effect="light" content="当前页" placement="top"><b                style="color:#f56c6c;cursor:pointer">{{                  currentPage                }}</b></el-tooltip>&nbsp;/&nbsp;            <el-tooltip class="item" effect="light" content="总页数" placement="top"><b                style="color:#67c23a;cursor:pointer">{{                  pageCount                }}</b></el-tooltip>          </p>        </div>        <div class="pdf-con">          <pdf ref="pdf" id="pdf" :src="getPdfSrc(item.pdfURL)" :page="currentPage" :rotate="pageRotate"            @num-pages="pageCount = $event" @page-loaded="currentPage = $event" @loaded="loadPdfHandler"></pdf>        </div>      </div>    </el-dialog>  </div></template><script>import pdf from 'vue-pdf'import { getPdfSrc } from "@/utils/pdfType";export default {  name: 'PdfDialog',  components: {    pdf  },  props: {    visible: false,    title: '',    index: 0,    pdfList: {      default: () => [],      type: Array    },  },  data() {    return {      value: 1,      src: `/files$this.$store.getters.getFiles.path`,      currentPage: 0,//pdf文件页码      // pageCount: 0,//pdf义件总页数      scale: 100,      pageRotate: 0,      isExit: false,    }  },  computed: {    item() {      return this.pdfList[this.index]    },    numPages() {      return this.visible ? this.item.numPages : 0    },    pageCount: {      get() {        return this.pdfList[this.index].numPages      },      set() { }    }  },  methods: {    handleClose() {      this.$emit('update:visible', false)    },    getPdfSrc(src) {      return getPdfSrc(src)    },    //pdf加戟时    loadPdfHandler() {      if (this.currentPage !== 0) return      this.value = this.currentPage = 1;//加载的时候先加截第一页    },    // 第一页    FirstPage() {      this.value = this.currentPage = 1;      this.isExit = false;    },    // / 最后一页    lastPage() {      this.value = this.currentPage = this.pageCount;      this.isExit = false;    },    // 改PDF页码VaL传过来区分上一页下一页的值,0上一页,1下一页    changePdfPage(val) {      if (val === 0 && this.currentPage > 1) {        this.currentPage--;      }      if (val === 1 && this.currentPage < this.pageCount) {        this.currentPage++;      }      this.value = this.currentPage;      this.isExit = false;    },    // /页码选择    pageSelect() {      this.currentPage = this.value;      this.isExit = false;    },    setIsExit() {      this.isExit = true;    },    //放大    scaleD() {      this.scale += 5;      this.$refs.pdf.$el.style.transform = 'scale(' + (this.scale / 100) + ')';    },    // / 1缩小    scalex() {      // /if (this.scale ==100){      //             /return;      // /      //     }      this.scale += -5;      this.$refs.pdf.$el.style.transform = 'scale(' + (this.scale / 100) + ')';    },    //顺时针    clock() {      this.pageRotate += 90;    },    // / 逆时针    counterclock() {      this.pageRotate -= 90;    },    downPDF() {      var url = this.item.pdfURL;      var tempLink = document.createElement("a");      tempLink.style.display = "none";      tempLink.href = url;      tempLink.setAttribute("download", "my.pdf");      if (typeof tempLink.download === "undefined") {        tempLink.setAttribute("target", "_blank");      }      document.body.appendChild(tempLink);      tempLink.click();      document.body.removeChild(tempLink);    },    printPDF() {      this.$refs.pdf.print();    }  }}</script><style scoped>.dialog-container {  height: 600px;  position: relative;}.pdf-con {  width: 100%;  height: calc(100% - 50px);  position: absolute;  top: 50px;  margin: 0 auto;  overflow: auto;}.btn {  margin: 20px 0px;}.main {  border: 2px solid #dcdfe6;  height: 700px;  overflow: auto;}.el-button--text {  font-size: 24px;}.el-select {  height: 40px;  line-height: 50px;  width: 101px;}::v-deep .el-select .el-input__suffix {  top: -4px;}.tools {  position: absolute;  right: 0;  display: flex;  justify-content: end;  z-index: 99;}.total {  width: 80px;  display: flex;  align-items: center;  justify-content: center;}</style>

2.  解决文字显示不全bug

//@/utils/pdfType.js
import pdf from 'vue-pdf'// 解决部分文字不显示的问题import CMapReaderFactory from 'vue-pdf-signature/src/CMapReaderFactory.js'export const getPdfSrc = (url) =>{    return pdf.createLoadingTask({        url,        CMapReaderFactory    })}