vue使用pdf-dist實(shí)現(xiàn)pdf預(yù)覽以及水印添加
更新時間:2023年10月19日 08:43:11 作者:菜鳥書生
這篇文章主要為大家詳細(xì)介紹了vue如何使用pdf-dist實(shí)現(xiàn)pdf預(yù)覽以及水印添加的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
一.使用pdf-dist插件將PDF文件轉(zhuǎn)換為一張張canvas圖片
npm install pdf-dist
二.頁面引入插件
const pdfJS = require("pdfjs-dist"); pdfJS.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/build/pdf.worker.entry");
三.渲染PDF
// 根據(jù)頁碼渲染相應(yīng)的PDF renderPage(num) { this.renderingPage = true; this.pdfData.promise.then((pdf) => { this.pdfPageNumber = pdf.numPages; pdf.getPage(num).then((page) => { // 獲取DOM中為預(yù)覽PDF準(zhǔn)備好的canvasDOM對象 let canvas = this.$refs.myCanvas; let ctx = canvas.getContext("2d"); // 獲取頁面比率 let ratio = this._getRatio(ctx); // 根據(jù)頁面寬度和視口寬度的比率就是內(nèi)容區(qū)的放大比率 let dialogWidth = this.$refs["canvasCont"].offsetWidth; let pageWidth = page.view[2] * ratio; let scale = dialogWidth / pageWidth; let viewport = page.getViewport({ scale }); // 記錄內(nèi)容區(qū)寬高,后期添加水印時需要 this.width = viewport.width * ratio; this.height = viewport.height * ratio; canvas.width = this.width; canvas.height = this.height; // 縮放比率 ctx.setTransform(ratio, 0, 0, ratio, 0, 0); let renderContext = { canvasContext: ctx, viewport: viewport, }; page.render(renderContext).promise.then(() => { this.renderingPage = false; this.pageNo = num; // 添加水印 this._renderWatermark(); }); }); }); }, // 計算角度 _getRatio(ctx) { let dpr = window.devicePixelRatio || 1; let bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; return dpr / bsr; },
四.添加水印
// 生成水印圖片 _initWatermark() { let canvas = document.createElement("canvas"); canvas.width = 200; canvas.height = 200; let ctx = canvas.getContext("2d"); ctx.rotate((-18 * Math.PI) / 180); ctx.font = "10px Vedana"; ctx.fillStyle = "rgba(0, 0, 0, 0.8)"; ctx.textAlign = "left"; ctx.textBaseline = "middle"; ctx.fillText(this.watermark, 10, 100); return canvas; },
五.完整代碼(帶翻頁)
<template> <div class="main-container"> <input type="file" ref="fielinput" @change="uploadFile" /> <div ref="canvasCont" class="canvas-container"> <canvas ref="myCanvas" class="pdf-container"></canvas> </div> <div class="pagination-wrapper"> <button @click="clickPre">上一頁</button> <span>第{{ pageNo }} / {{ pdfPageNumber }}頁</span> <button @click="clickNext">下一頁</button> </div> </div> </template> <script> const pdfJS = require("pdfjs-dist"); pdfJS.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/build/pdf.worker.entry"); export default { props: { watermark: { type: String, default: "水印文字水印文字水印文字", }, }, mounted() {}, data() { return { pageNo: null, pdfPageNumber: null, renderingPage: false, pdfData: null, // PDF的base64 scale: 1, // 縮放值 width: "", height: "", }; }, methods: { uploadFile() { let inputDom = this.$refs.fielinput; let file = inputDom.files[0]; let reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => { let data = atob( reader.result.substring(reader.result.indexOf(",") + 1) ); this.loadPdfData(data); }; }, loadPdfData(data) { // 引入pdf.js的字體 let CMAP_URL = "https://unpkg.com/pdfjs-dist@2.0.943/cmaps/"; //讀取base64的pdf流文件 this.pdfData = pdfJS.getDocument({ data: data, // PDF base64編碼 cMapUrl: CMAP_URL, cMapPacked: true, }); this.renderPage(1); }, // 根據(jù)頁碼渲染相應(yīng)的PDF renderPage(num) { this.renderingPage = true; this.pdfData.promise.then((pdf) => { this.pdfPageNumber = pdf.numPages; pdf.getPage(num).then((page) => { // 獲取DOM中為預(yù)覽PDF準(zhǔn)備好的canvasDOM對象 let canvas = this.$refs.myCanvas; let ctx = canvas.getContext("2d"); // 獲取頁面比率 let ratio = this._getRatio(ctx); // 根據(jù)頁面寬度和視口寬度的比率就是內(nèi)容區(qū)的放大比率 let dialogWidth = this.$refs["canvasCont"].offsetWidth; let pageWidth = page.view[2] * ratio; let scale = dialogWidth / pageWidth; let viewport = page.getViewport({ scale }); // 記錄內(nèi)容區(qū)寬高,后期添加水印時需要 this.width = viewport.width * ratio; this.height = viewport.height * ratio; canvas.width = this.width; canvas.height = this.height; // 縮放比率 ctx.setTransform(ratio, 0, 0, ratio, 0, 0); let renderContext = { canvasContext: ctx, viewport: viewport, }; page.render(renderContext).promise.then(() => { this.renderingPage = false; this.pageNo = num; // 添加水印 this._renderWatermark(); }); }); }); }, // 計算角度 _getRatio(ctx) { let dpr = window.devicePixelRatio || 1; let bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; return dpr / bsr; }, // 在畫布上渲染水印 _renderWatermark() { let canvas = this.$refs.myCanvas; let ctx = canvas.getContext("2d"); // 平鋪水印 let pattern = ctx.createPattern(this._initWatermark(), "repeat"); ctx.rect(0, 0, this.width, this.height); ctx.fillStyle = pattern; ctx.fill(); }, // 生成水印圖片 _initWatermark() { let canvas = document.createElement("canvas"); canvas.width = 200; canvas.height = 200; let ctx = canvas.getContext("2d"); ctx.rotate((-18 * Math.PI) / 180); ctx.font = "10px Vedana"; ctx.fillStyle = "rgba(0, 0, 0, 0.8)"; ctx.textAlign = "left"; ctx.textBaseline = "middle"; ctx.fillText(this.watermark, 10, 100); return canvas; }, clickPre() { if (!this.renderingPage && this.pageNo && this.pageNo > 1) { this.renderPage(this.pageNo - 1); } }, clickNext() { if ( !this.renderingPage && this.pdfPageNumber && this.pageNo && this.pageNo < this.pdfPageNumber ) { this.renderPage(this.pageNo + 1); } }, }, }; </script> <style scoped> .main-container { display: flex; flex-direction: column; align-items: center; } .canvas-container { width: 100%; height: 100%; border: 1px dashed black; position: relative; display: flex; justify-content: center; } .pdf-container { width: 100%; height: 100%; } .pagination-wrapper { display: flex; justify-content: center; align-items: center; } </style>
六.完整代碼(滑動)
<template> <div class="main-container"> <input type="file" ref="fielinput" @change="uploadFile" /> <div ref="canvasCont" class="canvas-container"> <canvas v-for="pageIndex in pdfPageNumber" :ref="`myCanvas${pageIndex}`" :key="pageIndex" class="pdf-container"></canvas> </div> </div> </template> <script> const pdfJS = require("pdfjs-dist"); pdfJS.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/build/pdf.worker.entry"); export default { props: { watermark: { type: String, default: "水印文字水印文字水印文字", }, }, mounted() {}, data() { return { pageNo: null, pdfPageNumber: null, renderingPage: false, pdfData: null, // PDF的base64 scale: 1, // 縮放值 width: "", height: "", }; }, methods: { uploadFile() { let inputDom = this.$refs.fielinput; let file = inputDom.files[0]; let reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => { let data = atob( reader.result.substring(reader.result.indexOf(",") + 1) ); this.loadPdfData(data); }; }, loadPdfData(data) { // 引入pdf.js的字體 let CMAP_URL = "https://unpkg.com/pdfjs-dist@2.0.943/cmaps/"; //讀取base64的pdf流文件 this.pdfData = pdfJS.getDocument({ data: data, // PDF base64編碼 cMapUrl: CMAP_URL, cMapPacked: true, }); this.renderPage(1); }, // 根據(jù)頁碼渲染相應(yīng)的PDF renderPage(num) { this.renderingPage = true; this.pdfData.promise.then((pdf) => { this.pdfPageNumber = pdf.numPages; pdf.getPage(num).then((page) => { // 獲取DOM中為預(yù)覽PDF準(zhǔn)備好的canvasDOM對象 let canvas = this.$refs[`myCanvas${num}`][0]; let ctx = canvas.getContext("2d"); // 獲取頁面比率 let ratio = this._getRatio(ctx); // 根據(jù)頁面寬度和視口寬度的比率就是內(nèi)容區(qū)的放大比率 let dialogWidth = this.$refs["canvasCont"].offsetWidth; let pageWidth = page.view[2] * ratio; let scale = dialogWidth / pageWidth; let viewport = page.getViewport({ scale }); // 記錄內(nèi)容區(qū)寬高,后期添加水印時需要 this.width = viewport.width * ratio; this.height = viewport.height * ratio; canvas.width = this.width; canvas.height = this.height; // 縮放比率 ctx.setTransform(ratio, 0, 0, ratio, 0, 0); let renderContext = { canvasContext: ctx, viewport: viewport, }; page.render(renderContext).promise.then(() => { this.renderingPage = false; this.pageNo = num; // 添加水印 this._renderWatermark(num); if(num < this.pdfPageNumber){ this.renderPage(num+1) } }); }); }); }, // 計算角度 _getRatio(ctx) { let dpr = window.devicePixelRatio || 1; let bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; return dpr / bsr; }, // 在畫布上渲染水印 _renderWatermark(num) { let canvas = this.$refs[`myCanvas${num}`][0]; let ctx = canvas.getContext("2d"); // 平鋪水印 let pattern = ctx.createPattern(this._initWatermark(), "repeat"); ctx.rect(0, 0, this.width, this.height); ctx.fillStyle = pattern; ctx.fill(); }, // 生成水印圖片 _initWatermark() { let canvas = document.createElement("canvas"); canvas.width = 200; canvas.height = 200; let ctx = canvas.getContext("2d"); ctx.rotate((-18 * Math.PI) / 180); ctx.font = "10px Vedana"; ctx.fillStyle = "rgba(0, 0, 0, 0.8)"; ctx.textAlign = "left"; ctx.textBaseline = "middle"; ctx.fillText(this.watermark, 10, 100); return canvas; }, }, }; </script> <style scoped> .main-container { display: flex; flex-direction: column; align-items: center; } .canvas-container { width: 100%; height: 100%; border: 1px dashed black; position: relative; /* display: flex; */ /* justify-content: center; */ } .pdf-container { width: 100%; height: 100%; } </style>
到此這篇關(guān)于vue使用pdf-dist實(shí)現(xiàn)pdf預(yù)覽以及水印添加的文章就介紹到這了,更多相關(guān)vue pdf預(yù)覽內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue+springboot實(shí)現(xiàn)登錄驗(yàn)證碼
這篇文章主要為大家詳細(xì)介紹了vue+springboot實(shí)現(xiàn)登錄驗(yàn)證碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-05-05Vue+Echart實(shí)現(xiàn)利用率表盤效果的示例代碼
這篇文章主要為大家詳細(xì)介紹了Vue如何利用Echart實(shí)現(xiàn)利用率表盤的效果,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,需要的可以參考一下2023-04-04Vue.js?element-plus使用圖標(biāo)不顯示問題的解決方式
近期在學(xué)習(xí)Vue時用elementUI時發(fā)現(xiàn)圖標(biāo)在頁面上顯示不出來,所以這篇文章主要給大家介紹了關(guān)于Vue.js?element-plus使用圖標(biāo)不顯示問題的解決方式,需要的朋友可以參考下2022-09-09Vue實(shí)現(xiàn)Hover功能(mouseover與mouseenter的區(qū)別及說明)
這篇文章主要介紹了Vue實(shí)現(xiàn)Hover功能(mouseover與mouseenter的區(qū)別及說明),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10Vue3?實(shí)現(xiàn)網(wǎng)頁背景水印功能的示例代碼
這篇文章主要介紹了Vue3?實(shí)現(xiàn)網(wǎng)頁背景水印功能,這里水印的字體大小、顏色和排布參考了企業(yè)微信的背景水印,使得看起來不那么突兀,需要的朋友可以參考下2022-08-08