首页 前端知识 vue-pdf 单页显示所有pdf页,实现滚动分页跳转分页显示

vue-pdf 单页显示所有pdf页,实现滚动分页跳转分页显示

2024-05-29 10:05:40 前端知识 前端哥 979 122 我要收藏

vue-pdf 单页显示所有,滚动显示实现分页跳转在这里插入图片描述

// 顶部按钮
<div class="my-dialog-title">
        <div class="pdf_btn" :style="isFullScreen ? {top: 0 } : ''">
          <div style="display: flex; align-items: center; width: 70%">
            <!-- 分页 -->
            <template style="display: flex;margin-right: 16px;font-size: 14px !important;;font-weight: 400">
              <el-button icon="el-icon-arrow-left" @click="prePage">上一页</el-button>
              <div class="page-count" style="margin: 0 8px; vertical-align: middle;line-height: 46px;height: 46px; font-size: 14px !important;">
                <el-input-number v-model="currentPageNum" :controls="false" :min="1" :max="numPages" style="width: 40px;vertical-align: middle" @change="pageNumChange" />
                / {{ numPages }}</div>
              <el-button @click="nextPage">下一页
                <i class="el-icon-arrow-right el-icon--right" />
              </el-button>
              <el-divider direction="vertical" />
            </template>
            <!-- 缩放 -->
            <template style="display: flex;margin-right: 16px;font-weight: 400;font-size: 14px !important;">
              <el-button icon="el-icon-zoom-in" @click="changeSize('big')" />
              <span style="display: inline-block;margin: 0 8px;font-size: 14px !important;">
                {{ styleObj.width + "%" }}
              </span>
              <el-button icon="el-icon-zoom-out" @click="changeSize('small')" />
            </template>
          </div>
          <div style="display: flex; width: 30%; justify-content: end; align-items: center">
            <!-- 最大化 -->
            <template style="display: flex;margin-right: 16px">
              <el-button
                icon="el-icon-full-screen"
                @click.native="fullScreenToggle"
              />
              <el-divider direction="vertical" />
            </template>
            <!-- 下载 -->
            <el-button
              icon="el-icon-download"
              type="warning"
              plain
              @click="downloadPdf"
            />
          </div>
        </div>
      </div>
// pdf 页面显示
<div class="my-dialog-content-box" style="position: relative">
        <div class="all-box" :style="{height: isFullScreen ? '100vh' : ''}" @scroll="scrollEvent($event)">
          <div v-for="i in numPages" :key="i" class="pdf-item" :style="{'width': styleObj.width + '%'}">
            <pdf
              ref="pdf"
              class="pdf-item"
              :src="pdfSrc"
              :page="i"
            />
          </div>
        </div>
      </div>

js

<script>
import pdf from "vue-pdf";

export default {
	components: { pdf },
	data() {
    return {
      remindShow: "加载文件中,文件较大请耐心等待...",
      url: process.env.VUE_APP_PROXY + "/file/downloadfile/", // 下载调用的接口地址
      pdfSrc: "",
      pageNum: 1,
      pageTotalNum: 1, // 总页数
      pdfShow: false, // pdf 显示刷新
      rotate: 0,
      sizeMultiple: 10,
      isFullScreen: false, // 全屏
      deviceListIsFinish: false, // 是否加载完成
      deviceListIsLoad: false, // 是否加载更多
      deviceTip: "",
      numPages: null,
      currentPageNum: 1,
      pdfItemHeight: 0, // 单页高度
      cutHeight: 0, // 切换高度
      // 加载进度
      loadedRatio: 0,
      styleObj: {
        width: 100
      }
    };
  },
async mounted() {
    const _dom = document.querySelector("body");
    // 将当前组件挂载到body下的最后
    _dom.insertBefore(this.$el, _dom.lastChild);
    this.getNumPages();
    window.addEventListener("resize", this.resize);
  },
  methods: {
  // 滚动
    scrollEvent(e) {
      if (e instanceof Event) {
        const el = e.target;
        const scrollTop = el.scrollTop;
        if (scrollTop > 0) {
          this.currentPageNum = Math.ceil((scrollTop + this.cutHeight) / this.pdfItemHeight);
        }
      }
    },
    // 跳转页面
    pageNumChange(e) {
      const pdfBox = document.getElementsByClassName("all-box")[0];
      if (e !== 1) {
        window.setTimeout(() => {
          pdfBox.scrollTop = this.pdfItemHeight * (this.currentPageNum - 1);
        }, 100);
      } else {
        window.setTimeout(() => {
          pdfBox.scrollTop = 1;
        }, 100);
      }
    },
    // 上一页
    prePage() {
      const pdfBox = document.getElementsByClassName("all-box")[0];
      if (this.currentPageNum > 1) {
        window.setTimeout(() => {
          pdfBox.scrollTop = this.pdfItemHeight * (this.currentPageNum - 1);
        }, 100);
        this.currentPageNum = this.currentPageNum - 1;
      } else {
        window.setTimeout(() => {
          pdfBox.scrollTop = this.pdfItemHeight * (this.numPages - 1);
        }, 100);
        this.currentPageNum = this.numPages;
      }
    },
    // 下一页
    nextPage() {
      const pdfBox = document.getElementsByClassName("all-box")[0];
      if (this.currentPageNum < this.numPages) {
        window.setTimeout(() => {
          pdfBox.scrollTop = this.pdfItemHeight * this.currentPageNum;
          this.currentPageNum = this.currentPageNum + 1;
        }, 100);
      } else {
        window.setTimeout(() => {
          pdfBox.scrollTop = 1;
        }, 100);
        this.currentPageNum = 1;
      }
    },
    resize() {
      if (!this._checkFull()) {
        this.isFullScreen = false;
        setTimeout(() => {
          this.cutHeight = (document.documentElement.clientHeight * 0.85 - 65) * 0.5;
          this.pdfItemHeight = document.getElementsByClassName("pdf-item")[0].offsetHeight + 30;
          const pdfBox = document.getElementsByClassName("all-box")[0];
          this.currentPageNum = Math.ceil((pdfBox.scrollTop + this.cutHeight) / this.pdfItemHeight);
        }, 200);
      }
    },
    // 变更pdf 大小
    changeSize(type) {
      if (type === "big") {
        if (this.sizeMultiple < 10) {
          this.sizeMultiple = this.sizeMultiple + 1;
        }
      } else {
        if (this.sizeMultiple > 5) {
          this.sizeMultiple = this.sizeMultiple - 1;
        }
      }
      this.styleObj.width = this.sizeMultiple * 10;
      setTimeout(() => {
        this.cutHeight = (document.documentElement.clientHeight * 0.85 - 65) * 0.5;
        this.pdfItemHeight = document.getElementsByClassName("pdf-item")[0].offsetHeight + 30;
        const pdfBox = document.getElementsByClassName("all-box")[0];
        this.currentPageNum = Math.ceil((pdfBox.scrollTop + this.cutHeight) / this.pdfItemHeight);
      }, 200);
    },
    getNumPages() {
      this.pdfSrc = pdf.createLoadingTask({ url: this.pdfUrl, CMapReaderFactory }, {
        // 进度条
        onProgress: (status) => {
          this.loadedRatio = (status.loaded / status.total) >= 1 ? 1 : status.loaded / status.total;
        }
      });
      this.$nextTick(() => {
        this.pdfShow = true;
      });
      this.pdfSrc.promise.then((pdf) => {
        console.log(pdf);
        this.numPages = pdf._pdfInfo.numPages;
        this.pageTotalNum = pdf._pdfInfo.numPages;
        this.pdfShow = true;
      }).catch((err) => {
        console.error("pdf 加载失败", err);
      }).finally(() => {
        setTimeout(() => {
          this.cutHeight = (document.documentElement.clientHeight * 0.85 - 65) * 0.5;
          this.pdfItemHeight = document.getElementsByClassName("pdf-item")[0].offsetHeight + 30;
        }, 500);
      });
    },
    // 全屏
    fullScreenToggle() {
      const $pdf = this.$el;
      if (this._checkFull()) {
        const eventOut =
          document.cancelFullScreen ||
          document.webkitCancelFullScreen ||
          document.mozCancelFullScreen ||
          document.msExitFullScreen;
        if (typeof eventOut !== "undefined" && eventOut) {
          eventOut.call(document);
        }
        this.isFullScreen = false;
      } else {
        if ($pdf.requestFullscreen) {
          $pdf.requestFullscreen();
        } else if ($pdf.webkitRequestFullscreen) {
          $pdf.webkitRequestFullscreen();
        } else if ($pdf.mozRequestFullscreen) {
          $pdf.mozRequestFullscreen();
        } else if ($pdf.msRequestFullscreen()) {
          $pdf.msRequestFullscreen();
        } else {
          this.$message.warning("该浏览器不支持全屏!");
          this.isFullScreen = false;
          return;
        }
        this.isFullScreen = true;
        setTimeout(() => {
          this.cutHeight = (document.documentElement.clientHeight - 65) * 0.5;
          this.pdfItemHeight = document.getElementsByClassName("pdf-item")[0].offsetHeight + 30;
          const pdfBox = document.getElementsByClassName("all-box")[0];
          this.currentPageNum = Math.ceil((pdfBox.scrollTop + this.cutHeight) / this.pdfItemHeight);
        }, 200);
      }
    },
    // 检查是否为全屏状态
    _checkFull() {
      let isFull =
        document.fullscreenElement ||
        document.mozFullScreenElement ||
        document.webkitFullscreenElement ||
        document.msFullscreenElement;
      if (isFull === undefined) isFull = false;
      return isFull;
    },
  }
}

</script>

<style scoped lang="less">
/deep/ .el-input__inner{
  font-size: 14px;
}
.progress {
  position: absolute;
  right: 50%;
  top: 50%;
  text-align: center;
}
.progress > span {
  color: #199edb;
  font-size: 14px;
}

.my-dialog{
  width: 100vw;
  height: 100vh;
  overflow-y: scroll;
  background-color: rgba(0,0,0,0.6);
  top: 0;
  left: 0;
  position: fixed;
  z-index: 3003 !important;
  .is-full-screen{
    top: 0 !important;
    left: 0 !important;
    height: 100vh !important;
    width: 100% !important;
    /deep/ .my-dialog-content-box{
      height: calc(100vh - 100px) !important;
      max-height: 100vh !important;
    }
  }
  .my-dialog-box{
    width: 500px;
    min-height: 300px;
    position: absolute;
    top: 5%;
    left: 30%;
    background: #FFFFFF;
    box-shadow: 0 8px 20px 0 rgba(215,221,228,0.5);
    border-radius: 8px;
    .my-dialog-title{
      width: 100%;
      height: 62px;
      line-height: 62px;
      box-shadow: 0 8px 20px 0 rgba(215,221,228,0.5);
      border-radius: 8px 8px 0 0;
      padding: 0 32px;
      position: relative;
      //overflow: hidden;
      box-sizing: border-box;
      .bottom-img{
        height: 5px;
        position: absolute;
        bottom: 0;
        left: 32px;
        line-height: 5px;
        img{
          height: 5px;
        }
      }
      .my-dialog-title-text{
        display: inline-block;
        height: 26px;
        font-size: 18px;
        font-weight: 600;
        color: #2D313D;
        line-height: 26px;
      }
      .my-dialog-title-remark{
        display: inline-block;
        height: 20px;
        font-size: 12px;
        font-weight: 400;
        color: #757A8A;
        line-height: 20px;
        margin-left: 8px;
      }
      .close-icon{
        display: inline-block;
        float: right;
        font-size: 14px;
      }
    }
    .my-dialog-content-box{
      max-height: calc(85vh - 65px);
      padding: 0 48px 32px 48px;
      overflow-y: auto;
      margin-top: 16px;
      position: relative;
    }
    .my-dialog-content-box::-webkit-scrollbar{
      display: none;
    }
  }
}
.pdf-item{
  margin: 0 auto 30px;
  overflow: hidden;
}
.pdf-box{
  margin-top: 60px;
  width: 100%;
  display: flex;
  justify-content: center;
}
/deep/ .my-dialog-content-box{
  padding: 0 40px !important;
  background: #d4d4d7;
  //background: #323639;
  position: relative;
}
.all-box{
  margin-top: 38px;
  width: 100%;
  height: calc(85vh - 100px);
  overflow-y: auto;
}
.all-box::-webkit-scrollbar{
  display: none;
}
.pdf_btn{
  height: 46px;
  line-height: 46px;
  width: 100%;
  position: absolute;
  top: 63px;
  left: 0;
  background-color: #fff;
  z-index: 3000;
  border-top: 1px solid #dcdee2;
  box-shadow: 0 1px 3px #e8eaec;
  padding: 0 20px;
  display: flex;
  justify-content: space-between
}
.custom-button {
  width: 90px;
  height: 46px;
  line-height: 46px;
  font-size: 14px;
  display: flex;
  padding: 0;
  justify-content: center;
  margin: 0 16px;
}
</style>
转载请注明出处或者链接地址:https://www.qianduange.cn//article/9956.html
标签
评论
发布的文章

使用 mapstructure 解析 json

2024-06-05 13:06:03

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!