100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > js 返回上一页面_pdf.js实战 含水印 电子签章解决方案

js 返回上一页面_pdf.js实战 含水印 电子签章解决方案

时间:2019-10-12 23:28:22

相关推荐

js 返回上一页面_pdf.js实战 含水印 电子签章解决方案

项目涉及到移动端查看电子合同的问题,前前后后试了三种方案,真是一步一个坑,三种方案各有各的优点,不水,直接上代码,按照自己的需求选择。

一、pdf-vue

直接使用vue-pdf插件,核心的代码是pdf.js,只不过就是自己封装了一下,优点是方便快捷,缺点是无法加载电子签章。

github地址: /FranckFreiburger/vue-pdf#readme

1、npm install pdf-vue --save

2、template代码

<template><div class="pdf" v-show="fileType === 'pdf'"><p class="arrow">// 上一页<span @click="changePdfPage(0)" class="turn" :class="{grey: currentPage==1}">Preview</span>{{currentPage}} / {{pageCount}}// 下一页<span @click="changePdfPage(1)" class="turn" :class="{grey: currentPage==pageCount}">Next</span></p>// 自己引入就可以使用,这里我的需求是做了分页功能,如果不需要分页功能,只要src就可以了<pdf:src="src" // src需要展示的PDF地址:page="currentPage" // 当前展示的PDF页码@num-pages="pageCount=$event" // PDF文件总页码@page-loaded="currentPage=$event" // 一开始加载的页面@loaded="loadPdfHandler"> // 加载事件</pdf></div></template>

3、js代码

import pdf from 'vue-pdf'export default {components: {pdf},data () {return {currentPage: 0, // pdf文件页码pageCount: 0, // pdf文件总页数fileType: 'pdf', // 文件类型src: '', // pdf文件地址}},created: {// 有时PDF文件地址会出现跨域的情况,这里最好处理一下this.src = pdf.createLoadingTask(this.src)}method: {// 改变PDF页码,val传过来区分上一页下一页的值,0上一页,1下一页changePdfPage (val) {// console.log(val)if (val === 0 && this.currentPage > 1) {this.currentPage--// console.log(this.currentPage)}if (val === 1 && this.currentPage < this.pageCount) {this.currentPage++// console.log(this.currentPage)}},// pdf加载时loadPdfHandler (e) {this.currentPage = 1 // 加载的时候先加载第一页}}}

使用非常方便,尤其是只需要翻页,或者不需要翻页的,强烈推荐。

二、pdf-dist

pdf-dist也是基于pdf.js的一个组件,只不过没有封装,需要自己配置,优点是可配置,可实现特殊的需求,缺点是需要自己封装,水印可加载,网上说可以加载电子签章,我的加载不出来,所以还是没采用。

1、npm install pdf-dist --save

2、封装一个pdf.vue

<template><div class="cpdf" id="cpdf"><div class="center"><canvas class="canvasstyle" id="the-canvas"></canvas><div class="contor"><button @click="prev" style="margin-right: 10px">上一页</button><span>Page: <span v-text="page_num"></span> / <span v-text="page_count"></span></span><button @click="next" style="margin-left: 10px">下一页</button></div></div></div></template><script>import PDFJS from 'pdfjs-dist'export default {name: 'c-pdf',// 接收父组件传来的参数 props: ['pdfurl'],components: { },data () {return {pdfDoc: null, // pdfjs 生成的对象pageNum: 1, //pageRendering: false,pageNumPending: null,scale: 1, // 放大倍数page_num: 0, // 当前页数page_count: 0, // 总页数maxscale: 2, // 最大放大倍数minscale: 0.8// 最小放大倍数}},methods: {renderPage (num) { // 渲染pdflet vm = thisthis.pageRendering = truelet canvas = document.getElementById('the-canvas')let ctx = canvas.getContext('2d')let bsr =ctx.webkitBackingStorePixelRatio ||ctx.mozBackingStorePixelRatio ||ctx.msBackingStorePixelRatio ||ctx.oBackingStorePixelRatio ||ctx.backingStorePixelRatio ||1let dpr = window.devicePixelRatio || 1let ratio = dpr / bsr// Using promise to fetch the pagethis.pdfDoc.getPage(num).then(function (page) {var viewport = page.getViewport(screen.availWidth / page.getViewport(1).width)// alert(vm.canvas.height)canvas.height = ratio * viewport.widthcanvas.width = ratio * viewport.heightcanvas.style.width = 1.5 * viewport.width + 'px'canvas.style.height = 1 * viewport.height + 'px'ctx.setTransform(ratio, 0, 0, ratio, 0, 0)// Render PDF page into canvas contextvar renderContext = {canvasContext: ctx,viewport: viewport}var renderTask = page.render(renderContext)// Wait for rendering to finishrenderTask.promise.then(function () {vm.pageRendering = falseif (vm.pageNumPending !== null) {// New page rendering is pendingvm.renderPage(vm.pageNumPending)vm.pageNumPending = null}})})vm.page_num = vm.pageNum},addscale () { // 放大if (this.scale >= this.maxscale) {return}this.scale += 0.1this.queueRenderPage(this.pageNum)},minus () { // 缩小if (this.scale <= this.minscale) {return}this.scale -= 0.1this.queueRenderPage(this.pageNum)},prev () { // 上一页let vm = thisif (vm.pageNum <= 1) {return}vm.pageNum--vm.queueRenderPage(vm.pageNum)},next () { // 下一页let vm = thisif (vm.pageNum >= vm.page_count) {return}vm.pageNum++vm.queueRenderPage(vm.pageNum)},closepdf () { // 关闭PDFthis.$emit('closepdf')},queueRenderPage (num) {if (this.pageRendering) {this.pageNumPending = num} else {this.renderPage(num)}}},computed: {ctx () {let id = document.getElementById('the-canvas')return id.getContext('2d')}},mounted () {let vm = thisPDFJS.getDocument(vm.pdfurl).then(function (pdfDoc_) { // 初始化pdfvm.pdfDoc = pdfDoc_vm.page_count = vm.pdfDoc.numPagesvm.renderPage(vm.pageNum)})}}</script><style lang="stylus" scoped>.cpdf {display: flex;justify-content: center;align-items: center;.center {text-align: center;height: 100%;overflow: hidden;padding-top: 20px;.contor {position: fixed;bottom: 30px;left: 0;width: 100%;z-index: 99999;font-size 30pxmargin-top 20pxmargin-bottom: 10px;}}}</style>

3、直接当成组件,引用就可以了

import cdpdf from '../../../components/pdf.vue'<cdpdf :pdfurl="pdfurl"></cdpdf>

一开始项目使用的是pdf-dist,因为后来电子签章显示不出来:

Warning: Unimplemented widget field type "Sig", falling back to base field type.

从网上搜了很多方法,说是需要修改pdf.work.js的源码,全局搜索AnnotationFlag.HIDDEN:

if(data.fieldType==='Sig') {warn('unimplemented annotation type: Widget signature');// 注释下面这行代码this.setFlags(AnnotationFlag.HIDDEN);}

可能是移动端使用微信浏览器的原因,注释掉代码还是不好使,只能再想其他办法了

三、pdf.js

最后用了最笨的办法,直接从GitHub拉下来pdf.js的demo,用iframe标签包住demo里的HTML文件,直接套着用,完美解决电子签章的问题:

1、从GitHub拉一下源码,或者从这个地址直接下载

https://mozilla.github.io/pdf.js/getting_started/#download

下载下来以后放在public文件下(3.x脚手架)

2、iframe标签直接粗暴的设置src

<iframe :src="pdfUrl" :style="{height: Height}" style="width: 100%"></iframe>this.pdfUrl = '../pdf/web/viewer.html?file=' + this.pdfurl, +'PDF'pdfUrl是iframe标签的URL,pdfurl是需要查看的PDF文件的url

总结

只要能实现需求的代码就是好代码,我的项目是移动端查看PDF文件,因为文件上有电子签章,所以尝试了好几种方案,个人还是推荐第二种方案,如果没有电子签章的情况下。

各位哥哥姐姐点个关注吧

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。