PDF查看器之pdfvuer
背景
公司需要实现一个PDF电子签章项目,使用到pdfvuer插件,
使用步骤
1. 加载包:pdfvuer
npm i pdfvuer
2. 引入
import pdfvuer from 'pdfvuer' // pdfvuer 版本为@1.6.1 import 'pdfjs-dist/build/pdf.worker.entry'复制代码
3. pdf预览(简化版)
<template> <pdf src="./static/test.pdf" :page="1"> <template slot="loading"> loading content here... </template> </pdf> </template> <script> import pdf from 'pdfvuer' export default { components: { pdf } }复制代码
4. pdf预览(带分页)
基于element+pdfvuer实现的分页预览pdf,可以跳转分页和滑动处理页码
<template> <!--使用 pdfvuer 实现 滑动浏览 单印章--> <div id="boxContent"> <div id="contentArea" class="centerArea"> <pdf ref="wrapper" :src="pdfData" v-for="i in numPages" :key="i" :id="i" :page="i" style="width:100%;" :scale="1"> <template slot="loading"> loading content here... </template> </pdf> </div> <div class="rightArea"> <div class="toolGroup"> <div class="page">第 {{ page }} / {{ numPages }} 页</div> <el-button type="primary" @click.stop="prePage">上一页</el-button> <el-button type="primary" @click.stop="nextPage">下一页</el-button> <div class="toolArea"> <span>跳到</span> <el-input v-model="inputPage" @keyup.enter.native="pageChange"/> <span>页</span> </div> </div> </div> </div> </template> <script> import pdfvuer from 'pdfvuer' // pdfvuer 版本为@1.6.1 import 'pdfjs-dist/build/pdf.worker.entry' export default { name: 'Pdfvuer', components: { pdf: pdfvuer }, data() { return { page: 1, // 当前页 numPages: 0, // 总页数 pdfData: undefined, inputPage: 1, // 输入的页码 } }, mounted() { this.getPdf() window.addEventListener('scroll', this.handleScroll, true); }, beforeDestroy() { window.removeEventListener('scroll', this.handleScroll, true); }, watch: { show: function (s) { if (s) { this.getPdf() } } }, methods: { // 获取 pdf 信息 getPdf() { this.pdfData = pdfvuer.createLoadingTask('/test.pdf') this.pdfData.then(pdf => { this.numPages = pdf.numPages }).catch(err => { console.log(err) }) }, // 滚动事件 滚动时更新页码 handleScroll() { let scrollTop = this.getScrollTop() // 滚动高度 let onePageHeight = this.getAttributeValue('page', 'height') // 单页面高度 this.page = Math.round(scrollTop / onePageHeight) + 1 // this.inputPage = this.page }, // 获取滚动高度 getScrollTop() { let scroll_top = 0; if (document.documentElement && document.documentElement.scrollTop) { scroll_top = document.documentElement.scrollTop; } else if (document.body) { scroll_top = document.body.scrollTop; } return scroll_top; }, // 滚动到固定位置 goTo(target) { let scrollT = document.body.scrollTop || document.documentElement.scrollTop if (scrollT > target) { let timer = setInterval(function () { let scrollT = document.body.scrollTop || document.documentElement.scrollTop let step = Math.floor(-scrollT / 6); document.documentElement.scrollTop = document.body.scrollTop = step + scrollT; if (scrollT <= target) { document.body.scrollTop = document.documentElement.scrollTop = target; clearTimeout(timer); } }, 20) } else if (scrollT === 0) { let timer = setInterval(function () { let scrollT = document.body.scrollTop || document.documentElement.scrollTop let step = Math.floor(300 / 3 * 0.7); document.documentElement.scrollTop = document.body.scrollTop = step + scrollT; if (scrollT >= target) { document.body.scrollTop = document.documentElement.scrollTop = target; clearTimeout(timer); } }, 20) } else if (scrollT < target) { let timer = setInterval(function () { let scrollT = document.body.scrollTop || document.documentElement.scrollTop let step = Math.floor(scrollT / 6); document.documentElement.scrollTop = document.body.scrollTop = step + scrollT; if (scrollT >= target) { document.body.scrollTop = document.documentElement.scrollTop = target; clearTimeout(timer); } }, 20) } else if (target === scrollT) { return false; } }, // 上一页 prePage() { let page = this.page; page = page > 1 ? page - 1 : 1; this.page = page; this.changeScrollTop() }, // 下一页 nextPage() { let page = this.page; page = page < this.numPages ? page + 1 : this.numPages; this.page = page; this.changeScrollTop() }, // 根据输入的页码跳转页面 pageChange() { let reg = /^[1-9]\d*$/ if (!reg.test(this.inputPage)) { this.$message.error('请输入正确的页码') return } this.inputPage > this.numPages ? this.page = this.numPages : this.page = ~~this.inputPage this.inputPage < 1 ? this.page = 1 : this.page = ~~this.inputPage this.changeScrollTop() }, // 根据页码变化修改页面滚动距离 changeScrollTop() { let onePageHeight = document.getElementById('contentArea').offsetHeight / this.numPages let scrollTo = onePageHeight * (this.page - 1) this.goTo(scrollTo) }, // 获取节点的某个属性值 只适用于获取 px 相关数据 getAttributeValue(className, attr) { let pageDiv = document.querySelector('.' + className); let attrsValue = getComputedStyle(pageDiv); let attrVal = attrsValue[attr] return Number(attrVal.substr(0, attrVal.length - 2)) // 截取掉 px }, } } </script>复制代码
5.踩坑集
a. 签章不显示问题
pdf预览电子签章显示问题解决方案
在node_modules/pdfjs-dist/build/pdf.worker.js注释掉这行代码 if (data.fieldType === "Sig") { data.fieldValue = null; // 注释掉底下这行 就可以显示电子签章 // this.setFlags(_util.AnnotationFlag.HIDDEN); } 在node_modules/pdfjs-dist/es5/build/pdf.worker.js注释掉这行代码 if (data.fieldType === "Sig") { data.fieldValue = null; // 注释掉底下这行 就可以显示电子签章 // _this3.setFlags(_util.AnnotationFlag.HIDDEN); }复制代码
修改成功后遇到新问题 node_modules每次重新npm install后修改代码消失指路手动修改 node_modules 中的依赖包(patch-package)
6.总结
代码指路练习平台还有pdf盖章拖拽代码和一些其他小插件的使用方法,有需要的小可爱们自行拉取。路过可以顺手点个赞哦 ~~
作者:祎是Yi不是Wei
链接:https://juejin.cn/post/7021405185054375967