| <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> |