pdfjs-dist实现pdf预览的组件

3,622 阅读1分钟

简介

pdfjs-dist 是一个通用的 PDF.js 构建库。

pdf.js 是一个技术原型主要用于在 HTML5 平台上展示 PDF 文档,无需任何本地技术支持。

码云地址

gitee.com/mirrors/pdf…

安装

npm i pdfjs-dist

引入

import PDFJS from "pdfjs-dist";

组件代码

<template>
  <el-dialog
    :title="title"
    :visible="visible"
    v-if="visible"
    :before-close="handleCancel"
    width="70%"
    :footer="null"
  >
    <div v-loading="loading">
      <div class="page-box">
        <div class="option-list" v-if="pageCount > 1">
          <el-button
            type="primary"
            :disabled="clickFlag || pageIndex == 1"
            @click="pageTurn(pageIndex--)"
          >
            上一页
          </el-button>
          <div class="page-num">
            <!-- 当前页码和总页数 -->
            {{ pageIndex }}/{{ pageCount }}
          </div>
          <el-button
            type="primary"
            :disabled="clickFlag || pageIndex == pageCount"
            @click="pageTurn(pageIndex++)"
          >
            下一页
          </el-button>
        </div>
      </div>
      <div class="modal-box" id="pdf-preview-box">
        <!-- 文件区域 -->
        <canvas id="the-canvas"></canvas>
      </div>
    </div>
  </el-dialog>
</template>

<script>
import PDFJS from "pdfjs-dist";

export default {
  name: "PdfPreview",
  components: {},
  props: {
    title: {
      type: String,
      default: "PDF文件预览",
    },
  },
  data() {
    return {
      pageIndex: 1,
      pageCount: 1,
      loading: true,
      visible: false,
      pdfDatas: null,
      clickFlag: false,
    };
  },
  watch: {},
  computed: {},
  methods: {
    initPdf(pdfurl) {
      this.visible = true;
      this.loading = true;
      // 引入pdf.js的字体
      let CMAP_URL = "https://unpkg.com/pdfjs-dist@2.0.943/cmaps/";
      PDFJS.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/build/pdf.worker.js");
      let loadingTask = PDFJS.getDocument({
        url: pdfurl, // PDF base64编码
        cMapUrl: CMAP_URL,
        cMapPacked: true,
      });
      let that = this;
      loadingTask.promise.then(
        function (pdf) {
          that.pageCount = pdf.numPages;
          that.pdfDatas = pdf;
          that.pageTurn(that.pageIndex);
          that.loading = false;
        },
        function (reason) {
          that.loading = false;
          console.error(reason);
        }
      );
    },
    pageTurn() {
      if (this.pageIndex < 1) this.pageIndex = 1;
      if (this.pageIndex > this.pageCount) this.pageIndex = this.pageCount;
      this.clickFlag = true;
      let that = this;
      this.pdfDatas.getPage(this.pageIndex).then(function (page) {
        let desiredWidth = document
          .getElementById("pdf-preview-box")
          .getBoundingClientRect().width;
        let viewport = page.getViewport({ scale: 1 });
        let scale = desiredWidth / viewport.width;
        let scaledViewport = page.getViewport({ scale });
        let canvas = document.getElementById("the-canvas");
        let context = canvas.getContext("2d");
        canvas.height = scaledViewport.height;
        canvas.width = scaledViewport.width;
        canvas.style.width = desiredWidth + "px";
        let renderContext = {
          canvasContext: context,
          viewport: scaledViewport,
        };
        page.render(renderContext);
        setTimeout(() => {
          that.clickFlag = false;
        }, 300);
      });
    },
    handleCancel(e) {
      this.visible = false;
      this.$emit("close");
    },
  },
  created() {},
  mounted() {},
};
</script>
<style lang="scss" scoped>
.wrapper {
}
.modal-box {
  width: 100%;
  height: 55vh;
  overflow: auto;
}

.page-box {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 50px;
  margin-bottom: 15px;
  .option-list {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    .page-num {
      min-width: 100px;
      text-align: center;
    }
  }
}

/deep/.el-dialog__body {
  padding: 0px 20px 30px;
}
</style>