<template> 
 | 
  <GlobalWindow 
 | 
      :title="title" 
 | 
      width="100%" 
 | 
      :visible.sync="visible" 
 | 
      :confirm-working="isWorking" 
 | 
      @confirm="confirm" 
 | 
  > 
 | 
  <div class="pdfView"> 
 | 
    <div class="show"> 
 | 
      <!--分页显示--> 
 | 
      <pdf 
 | 
          ref="pdf" 
 | 
          :src="pdfUrl" 
 | 
          :page="pageNum" 
 | 
          :rotate="pageRotate" 
 | 
          @password="password" 
 | 
          @progress="loadedRatio = $event" 
 | 
          @loaded="onLoadSuccess" 
 | 
          @page-loaded="pageLoaded($event)" 
 | 
          @num-pages="pageTotalNum = $event" 
 | 
          @error="pdfError($event)" 
 | 
          @link-clicked="page = $event" 
 | 
      > 
 | 
      </pdf> 
 | 
    </div> 
 | 
    <div class="pdf_footer"> 
 | 
      <div class="info"> 
 | 
        <div>当前页数/总页数:{{ pageNum }}/{{ pageTotalNum }}</div> 
 | 
        <!-- <div>进度:{{ loadedRatio }}</div> --> 
 | 
        <!-- <div>页面加载成功: {{ curPageNum }}</div> --> 
 | 
      </div> 
 | 
    </div> 
 | 
  </div> 
 | 
    <template  v-slot:footer> 
 | 
      <el-button-group> 
 | 
        <el-button type="primary" icon="el-icon-arrow-left" style="border-radius: 30px 0 0 30px" @click.stop="prePage">上一页</el-button> 
 | 
        <el-button type="primary" @click.stop="nextPage" style="border-radius: 0 30px 30px 0">下一页<i class="el-icon-arrow-right el-icon--right"></i></el-button> 
 | 
      </el-button-group> 
 | 
      <el-button-group style="margin-left: 30px"> 
 | 
        <el-button type="primary" style="border-radius: 30px 0 0 30px" @click="scaleD">放大</el-button> 
 | 
        <el-button type="primary" style="border-radius: 0 30px 30px 0" @click="scaleX">缩小</el-button> 
 | 
      </el-button-group> 
 | 
      <el-button-group style="margin-left: 30px"> 
 | 
        <el-button type="primary" style="border-radius: 30px 0 0 30px" @click="download(pdfUrl)">下载</el-button> 
 | 
        <el-button @click="visible=false"  style="border-radius: 0 30px 30px 0" >关闭</el-button> 
 | 
      </el-button-group> 
 | 
    </template> 
 | 
  </GlobalWindow> 
 | 
</template> 
 | 
  
 | 
<script> 
 | 
import BaseOpera from '@/components/base/BaseOpera' 
 | 
import GlobalWindow from '@/components/common/GlobalWindow' 
 | 
import pdf from 'vue-pdf' 
 | 
export default { 
 | 
  name: 'OperaPdsViewerWindow', 
 | 
  extends: BaseOpera, 
 | 
  components: { 
 | 
    GlobalWindow, 
 | 
    pdf 
 | 
  }, 
 | 
  data () { 
 | 
    return { 
 | 
      pdfUrl: '', 
 | 
      // 总页数 
 | 
      pageTotalNum: 1, 
 | 
      // 当前页数 
 | 
      pageNum: 1, 
 | 
      // 加载进度 
 | 
      loadedRatio: 0, 
 | 
      // 页面加载完成 
 | 
      curPageNum: 0, 
 | 
      // 放大系数 默认百分百 
 | 
      scale: 100, 
 | 
      // 旋转角度 ‘90’的倍数才有效 
 | 
      pageRotate: 0, 
 | 
      // 单击内部链接时触发 (目前我没有遇到使用场景) 
 | 
      page: 0, 
 | 
      // 当前页数 
 | 
      numPages: 1, 
 | 
      // 预览路径 
 | 
      localUrl: '', 
 | 
      loading: true 
 | 
    } 
 | 
  }, 
 | 
  methods: { 
 | 
    open (title, target) { 
 | 
      this.pdfUrl = target 
 | 
      this.title = title 
 | 
      this.localUrl = '' 
 | 
      this.localUrl = this.pdfUrl 
 | 
      console.log(this.pdfUrl) 
 | 
      const loadingTask = pdf.createLoadingTask(this.localUrl) 
 | 
      loadingTask.promise.then(pdf => { 
 | 
        this.numPages = pdf.numPages 
 | 
        this.loading = false 
 | 
      }).catch((err) => { 
 | 
        this.$message.error('文件加载失败,可尝试下载文件查看!') 
 | 
      }) 
 | 
      this.visible = true 
 | 
    }, 
 | 
    onLoadSuccess (pdf) { 
 | 
      // PDF加载成功后,可以将初始页码设置为第一页 
 | 
      this.pageNum = 1 
 | 
    }, 
 | 
    download (url) { 
 | 
      const link = document.createElement('a') 
 | 
      // 这里是将链接地址url转成blob地址, 
 | 
      fetch(url) 
 | 
        .then((res) => res.blob()) 
 | 
        .then((blob) => { 
 | 
          link.href = URL.createObjectURL(blob) 
 | 
          // 下载文件的名称及文件类型后缀 
 | 
          link.download = this.title 
 | 
          document.body.appendChild(link) 
 | 
          link.click() 
 | 
          // 在资源下载完成后 清除 占用的缓存资源 
 | 
          window.URL.revokeObjectURL(link.href) 
 | 
          document.body.removeChild(link) 
 | 
        }) 
 | 
    }, 
 | 
    // 下载PDF 
 | 
    fileDownload (data, fileName) { 
 | 
      const blob = new Blob([data], { 
 | 
        // type类型后端返回来的数据中会有,根据自己实际进行修改 
 | 
        type: 'application/pdf' 
 | 
      }) 
 | 
      const filename = fileName || 'pdf.pdf' 
 | 
      if (typeof window.navigator.msSaveBlob !== 'undefined') { 
 | 
        window.navigator.msSaveBlob(blob, filename) 
 | 
      } else { 
 | 
        var blobURL = URL.createObjectURL(blob) 
 | 
        // 创建隐藏<a>标签进行下载 
 | 
        var tempLink = document.createElement('a') 
 | 
        tempLink.style.display = 'none' 
 | 
        tempLink.href = blobURL 
 | 
        tempLink.setAttribute('download', filename) 
 | 
        if (typeof tempLink.download === 'undefined') { 
 | 
          tempLink.setAttribute('target', '_blank') 
 | 
        } 
 | 
        document.body.appendChild(tempLink) 
 | 
        tempLink.click() 
 | 
        document.body.removeChild(tempLink) 
 | 
        window.URL.revokeObjectURL(blobURL) 
 | 
      } 
 | 
    }, 
 | 
    // 打印 
 | 
    pdfPrintAll () { 
 | 
      this.$refs.pdf.print() 
 | 
    }, 
 | 
    // 放大 
 | 
    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.pageTotalNum 
 | 
      this.pageNum = p 
 | 
    }, 
 | 
    // 切换下一页 
 | 
    nextPage () { 
 | 
      var p = this.pageNum 
 | 
      p = p < this.pageTotalNum ? p + 1 : 1 
 | 
      this.pageNum = p 
 | 
    }, 
 | 
    // pdf 有密码 则需要输入秘密 
 | 
    password (updatePassword, reason) { 
 | 
      updatePassword(prompt('password is "test"')) 
 | 
      console.log('...reason...') 
 | 
      console.log(reason) 
 | 
      console.log('...reason...') 
 | 
    }, 
 | 
    // 页面加载成功  当前页数 
 | 
    pageLoaded (e) { 
 | 
      console.log('pageLoaded', e) 
 | 
      this.$emit('current', e) 
 | 
      this.curPageNum = e 
 | 
    }, 
 | 
    // 异常监听 
 | 
    pdfError (error) { 
 | 
      console.error('异常监听', error) 
 | 
    } 
 | 
    // getNumPages() { 
 | 
    //   let loadingTask = pdf.createLoadingTask(this.pdfUrl); 
 | 
    //   loadingTask.promise.then(pdf => { 
 | 
    //     this.numPages = pdf.numPages; 
 | 
    //     console.log('this.numPages', this.numPages) 
 | 
    //   }).catch((err) => { 
 | 
    //     console.error('pdf加载失败') 
 | 
    //   }) 
 | 
    // }, 
 | 
  } 
 | 
} 
 | 
</script> 
 | 
  
 | 
<style lang="scss" scoped> 
 | 
.pdfView { 
 | 
  padding: 20px; 
 | 
  .show { 
 | 
    overflow: auto; 
 | 
    margin: auto; 
 | 
    max-width: 100%; 
 | 
    //height: 80vh; 
 | 
    max-height: 100%; 
 | 
    border: 2px solid #eee; 
 | 
    border-radius: 6px; 
 | 
    background-color: #eeeeee; 
 | 
    // 滚动条样式 
 | 
    &::-webkit-scrollbar { 
 | 
      width: 10px; 
 | 
    } 
 | 
    &::-webkit-scrollbar-thumb { 
 | 
      background-color: #999; 
 | 
      border-radius: 6px; 
 | 
    } 
 | 
    &::-webkit-scrollbar-track { 
 | 
      background-color: transparent; 
 | 
      border-radius: 6px; 
 | 
    } 
 | 
  } 
 | 
  .pdf_footer { 
 | 
    position: fixed; 
 | 
    bottom: 10px; 
 | 
    font-size: 14px; 
 | 
    //left: 0; 
 | 
    right: 50px; 
 | 
    text-align: right; 
 | 
    //width: 50%; 
 | 
    padding: 10px 0; 
 | 
    background-color: rgba(255, 255, 255, 0.5); 
 | 
    .info { 
 | 
      display: flex; 
 | 
      flex-wrap: wrap; 
 | 
      justify-content: space-around; 
 | 
      div { 
 | 
        //width: 30%; 
 | 
      } 
 | 
    } 
 | 
    .operate { 
 | 
      margin: 10px 0 0; 
 | 
      display: flex; 
 | 
      flex-wrap: wrap; 
 | 
      justify-content: space-between; 
 | 
      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> 
 |