PDF文件实现在线盖章
需求:需要實現給預覽的PDF文件,蓋上電子印章
🌼?🌼?實現效果:(注:pdf文件資源和圖片資源都是網上獲取到的)
安裝插件
npm install pdfjs-dist --save
引入
import PDFJS from 'pdfjs-dist';PDFJS.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker.js';這兩個文件包含了獲取、解析和展示PDF文檔的方法,但是解析和渲染PDF需要較長的時間,可能會阻塞其它JS代碼的運行。
PDF.js的API都會返回一個Promise,使得我們可以優雅的處理異步操作。
如果引入報錯
修改參考:關于前端PDF顯示和蓋章(vue)_Harrietjia的博客-CSDN博客PDFhttps://www.jianshu.com/p/94cf6ddcb299https://segmentfault.com/a/1190000016963084https://blog.csdn.net/qq_38188485/article/details/104452542
使用canvas當作為預覽pdf文件的畫布
<div id="pdf-container" class="center"></div>渲染PDF文件(一次渲染文件的所有頁)
initPdf(flag) {let vm = this;var val = vm.pdfurl;if (val === '' || val === undefined) return;// 用于異步獲取PDf文檔,發送多個Ajax請求以塊的形式下載文檔。它返回一個Promise,該Promise的成功回調傳遞一個對象,該對象包含PDF文檔的信息,該回調中的代碼將在完成PDf文檔獲取時執行。PDFJS.getDocument(val).then(function(pdfDoc_) {// 初始化pdfvm.pdfDoc = pdfDoc_;vm.pageCount = vm.pdfDoc.numPages;// 根據頁碼創建畫布let id = '';let idTemplate = 'cw-pdf-';if (flag === 'init') {vm.createSeriesCanvas(vm.pdfDoc.numPages, idTemplate);}// 將pdf渲染到畫布上去for (var i = 1; i <= vm.pdfDoc.numPages; i++) {id = idTemplate + i;vm.renderPDF(vm.pdfDoc, i, id);}}).catch(function(err) {if (err) {console.log(err);vm.throwerr(vm.pdfurl);}});},renderPDF(pdf, i, id) {let vm = this;pdf.getPage(i).then(function(page) {// 準備用于渲染的 canvas 元素var canvas = document.getElementById(id);var context = canvas.getContext('2d');var viewport = page.getViewport(vm.compuscale, vm.leftrotate);canvas.height = viewport.height;canvas.width = viewport.width;// 將 PDF 頁面渲染到 canvas 上下文中var renderContext = {canvasContext: context,viewport: viewport};page.render(renderContext);});},createSeriesCanvas(num, template) {var id = '';for (var j = 1; j <= num; j++) {id = template + j;this.createPdfContainer(id, 'canvasstyle');}},createPdfContainer(id, className) {var pdfContainer = document.getElementById('pdf-container');var divNew = document.createElement('div');var canvasNew = document.createElement('canvas');divNew.id = 'div-' + id;canvasNew.id = id;canvasNew.className = className;divNew.appendChild(canvasNew);pdfContainer.appendChild(divNew);},getPage():用于獲取PDF文檔中的各個頁面。
getViewport():針對提供的展示比例,返回PDf文檔的頁面尺寸。
render():渲染PDF。
此時pdf文件就可以基本顯示了。
之后實現印章的拖拽功能。
基本思路:我們在點擊印章的時候,(鼠標按下)新創建一個和印章一模一樣的節點(可以是克隆)并添加在pdf容器內(也就是作為pdf容器的子節點),之后移動鼠標(拖拽),移動的是這個新克隆出來的節點,此時根據移動的位置,給該信節點設置定位的像素值,鼠標抬起,取消鼠標移動事件。每個已經拖拽過去的印章還得支持改變位置,所以每個新戈隆的節點,需要添加對應的事件;每個拖拽的印章還需要計算邊界值。
數據源data:
data() {return {cloneDragSeal: null,draggedSeal: null,scrollTop: 0,dragSealList: null,sealList: [{url: require('../../../assets/images/yinzhang1.png'),id: 'seal1'},{url: require('../../../assets/images/yinzhang2.png'),id: 'seal2'}],pdfurl:'https://dakaname.oss-cn-hangzhou.aliyuncs.com/file/2018-12-28/1546003237411.pdf', // pdf鏈接地址pdfDoc: null, // pdfjs 生成的對象pageNum: 1, //pageRendering: false,pageNumPending: null,compuscale: 1, // 放大倍數leftrotate: 0,scale: 1.6, // 放大倍數 相當于初始倍數pageNumC: 0, // 當前頁數pageCount: 0, // 總頁數gotopageNum: '', // 跳轉到指定的頁面// maxscale: 2, //最大放大倍數// minscale: 0.8, //最小放大倍數isready: false};},印章渲染:
<div class="side-bar"><h2>推拽章的信息</h2><div class="side-barinfo"><!-- <div class="sign-img" @mousedown="signPic" @mouseup="removeSignPic"> --><div style="display: flex; justify-content: space-around"><div><divv-for="item in sealList":key="item.id"class="drag_seal"style="width: 100px; height: 100px":sealId="item.id"><img:src="item.url"alt=""style="width: 100px; height: 100px"/><!-- img的鼠標按按下 事件失效 覆蓋一個div --><!-- <div class="seal_img_copy"></div> --><!-- <i class="el-icon-close"></i> --></div></div></div></div></div>給印章添加事件
let bgDom = document.getElementsByClassName('bg_mask')[0]; bgDom.addEventListener('scroll', this.scrollFn);sealAddEvent() {this.dragSealList = document.getElementsByClassName('drag_seal');[...this.dragSealList].forEach((item) => {// console.log(item.getAttribute('sealId'),'item');item.addEventListener('mousedown', (e) => {this.itemMouseDownFn({ e: e, id: item.getAttribute('sealId') });});// item.addEventListener('mouseup', (e) => {// this.itemMouseupFn({ e: e, id: item.getAttribute('sealId') });// });});},事件函數定義
itemMouseupFn(e) {if (!this.cloneDragSeal) {return false;}document.removeEventListener('mousemove', this.signmouseMve, false);let pdfContainer = document.getElementById('pdf-container');// 找邊界值let left = this.cloneDragSeal.style.left.replace('px', '');if (left < 0 ||e.clientX > pdfContainer.offsetLeft + pdfContainer.clientWidth) {this.cloneDragSeal && pdfContainer.removeChild(this.cloneDragSeal);}this.cloneDragSeal = null;},draggedSealOverFn(e) {let nextSibling = e.target.nextSibling;if (nextSibling) nextSibling.style.display = '';},draggedSealOutFn(e) {let nextSibling = e.target.nextSibling;if (nextSibling) nextSibling.style.display = 'none';},draggedSealUpFn(e) {if (!this.draggedSeal) {return false;}document.removeEventListener('mousemove', this.draggedSealMove, false);let pdfContainer = document.getElementById('pdf-container');// 找邊界值let left = this.draggedSeal.style.left.replace('px', '');if (left < 0 ||e.clientX > pdfContainer.offsetLeft + pdfContainer.clientWidth) {this.draggedSeal && pdfContainer.removeChild(this.draggedSeal);}this.draggedSeal = null;},draggedSealDownFn(e) {this.draggedSeal = e.target.parentNode;console.log('draggedSealDownFn', e.target.parentNode);document.addEventListener('mousemove', this.draggedSealMove, false);},// 已經拖拽過去的印章 移動事件draggedSealMove(e) {e.preventDefault();let pdfContainer = document.getElementById('pdf-container');this.draggedSeal.style.position = 'absolute';// this.draggedSeal.style.top =// ((e.clientY -// pdfContainer.offsetTop -// this.draggedSeal.clientHeight / 2 +// this.scrollTop -// 108) /// pdfContainer.clientHeight) *// 100 +// '%';this.draggedSeal.style.top =e.clientY -pdfContainer.offsetTop -this.draggedSeal.clientHeight / 2 -108 +this.scrollTop +'px';this.draggedSeal.style.left =e.clientX -pdfContainer.offsetLeft -this.draggedSeal.clientWidth / 2 +'px';},// 待拖拽印章的 鼠標按下事件函數itemMouseDownFn(obj) {console.log('按下');let e = obj.e || window.event;e.preventDefault();// 鼠標 按下 開始移動// 1、原印章不變 新創建一個印章(克隆)this.cloneDragSeal = e.currentTarget.cloneNode(true);let delBtn = document.createElement('div');delBtn.innerText = 'X';delBtn.style.position = 'absolute';delBtn.style.top = 0;delBtn.style.right = 0;delBtn.style.display = 'none';delBtn.addEventListener('click', this.sealDelFn);this.cloneDragSeal.appendChild(delBtn);this.cloneDragSeal.addEventListener('mousedown', this.draggedSealDownFn);this.cloneDragSeal.addEventListener('mouseup', this.draggedSealUpFn);this.cloneDragSeal.addEventListener('mouseover', this.draggedSealOverFn);this.cloneDragSeal.addEventListener('mouseout', this.draggedSealOutFn);let pdfContainer = document.getElementById('pdf-container');this.cloneDragSeal.className = 'dragged_seal';pdfContainer.appendChild(this.cloneDragSeal);document.addEventListener('mousemove', this.signmouseMve, false);document.addEventListener('mouseup', this.itemMouseupFn, false);},scrollFn(e) {this.scrollTop = e.target.scrollTop;},signmouseMve(e) {// let e = e || window.event;e.preventDefault();let pdfContainer = document.getElementById('pdf-container');this.cloneDragSeal.style.position = 'absolute';// left: 鼠標點擊位置 - 當前頁碼pdf的offsetLeft// top: 鼠標點擊位置 - headerthis.cloneDragSeal.style.top =e.clientY -pdfContainer.offsetTop -this.cloneDragSeal.clientHeight / 2 -108 +this.scrollTop +'px';},至于和后端交互上的設計,還在實驗中,請稍后。
總結
以上是生活随笔為你收集整理的PDF文件实现在线盖章的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Angular安装命令
- 下一篇: C语言:带你轻松干掉 腾讯笔试大题 带环