vue使用pdf-dist實(shí)現(xiàn)pdf預(yù)覽以及水印添加
一.使用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對(duì)象
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ū)寬高,后期添加水印時(shí)需要
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();
});
});
});
},
// 計(jì)算角度
_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對(duì)象
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ū)寬高,后期添加水印時(shí)需要
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();
});
});
});
},
// 計(jì)算角度
_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>六.完整代碼(滑動(dòng))
<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對(duì)象
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ū)寬高,后期添加水印時(shí)需要
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)
}
});
});
});
},
// 計(jì)算角度
_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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue+springboot實(shí)現(xiàn)登錄驗(yàn)證碼
這篇文章主要為大家詳細(xì)介紹了vue+springboot實(shí)現(xiàn)登錄驗(yàn)證碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
Vue+Echart實(shí)現(xiàn)利用率表盤效果的示例代碼
這篇文章主要為大家詳細(xì)介紹了Vue如何利用Echart實(shí)現(xiàn)利用率表盤的效果,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下2023-04-04
Vue.js?element-plus使用圖標(biāo)不顯示問題的解決方式
近期在學(xué)習(xí)Vue時(shí)用elementUI時(shí)發(fā)現(xiàn)圖標(biāo)在頁面上顯示不出來,所以這篇文章主要給大家介紹了關(guān)于Vue.js?element-plus使用圖標(biāo)不顯示問題的解決方式,需要的朋友可以參考下2022-09-09
Vue實(shí)現(xiàn)Hover功能(mouseover與mouseenter的區(qū)別及說明)
這篇文章主要介紹了Vue實(shí)現(xiàn)Hover功能(mouseover與mouseenter的區(qū)別及說明),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
Vue3?實(shí)現(xiàn)網(wǎng)頁背景水印功能的示例代碼
這篇文章主要介紹了Vue3?實(shí)現(xiàn)網(wǎng)頁背景水印功能,這里水印的字體大小、顏色和排布參考了企業(yè)微信的背景水印,使得看起來不那么突兀,需要的朋友可以參考下2022-08-08
詳解vue-property-decorator使用手冊(cè)
這篇文章主要介紹了vue-property-decorator使用手冊(cè),文中較詳細(xì)的給大家介紹了他們的用法,通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07

