vue 纯前端预览pdf,纯前端实现pdf加水印下载文件也带水印,防止pdf下载
vue项目使用pdfh5+pdf-lib+ @pdf-lib/fontkit实现吹前端预览pdf并且实现pdf加水印下载pdf文件也带水印
效果图
1.pdf预览
原理:主要是利用pdfh5这个插件来完成的
使用方法:
1.页面需要有一个容器例子:<div id="demo"></div>
2.下载pdfh5插件
npm install pdfh5
(注意:webpack5之后不会下载polyfill 需要手动下载 所以引入pdfh5的时候会报错)
解决方案:下载 node-polyfill-webpack-plugin
npm install node-polyfill-webpack-plugin
之后再vue.config.js里面配置
// 头部引入
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
//...
configureWebpack: {
plugins: [new NodePolyfillPlugin()],
}
})
3.解决报错之后下面直接使用
this.pdfh5 = new Pdfh5("#demo", {
pdfurl: this.url,
});
-----另外 需要我们引入css样式 还需要我们自己写一点css样式来修改转成pdf后里面图片过大 再最下面
2.pdf加水印
原理:利用的是将pdf文件转化成二进制文件 再用画图的方式往里面画文字
主要利用插件:pdf-lib @pdf-lib/fontkit
npm install pdf-lib
npm install @pdf-lib/fontkit
(注意:这里使用字体的时候需要引入两个字体包再同级目录下的font下的两个包)
这里面的预览还是用到的pdfh5来预览的
使用方法:直接调用addWarker(url,warkerName) 方法
参数说明:url:需要添加水印的pdf文件地址
warkerName添加水印字
注意:一半这种都不允许下载 禁止鼠标右击事件就是再我们的元素上加上@contextmenu.prevent事件
并且加css样式:
* {
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
下载pdf还是用的pdfh5中的download方法
另外附上完整代码
<template>
<div>
<div class="xlsx-content">
<div class="btnPdf">
<button @click="viewpdf">预览pdf</button>
<button @click="currenNum">查看当前页数</button>
<button @click="addWarker">pdf加水印</button>
<button @click="downPdf">下载pdf</button>
</div>
<div class="pdf" @contextmenu.prevent>
<div id="demo"></div>
</div>
</div>
</div>
</template>
<script>
import Pdfh5 from "pdfh5";
import "pdfh5/css/pdfh5.css";
import fontkit from "@pdf-lib/fontkit";
import {
degrees,
PDFDocument,
rgb
} from "pdf-lib";
export default {
components: {},
data() {
return {
url: "自己输入pdf地址",
pdfh5: null,
};
},
methods: {
// 预览pdf
viewpdf() {
(this.url =
"自己输入pdf地址"),
(this.pdfh5 = new Pdfh5("#demo", {
pdfurl: this.url,
}));
this.pdfh5.on("render", function (status, msg, time) {
this.goto(5);
});
},
// 获取当前进度
currenNum() {
console.log(this.pdfh5, this.pdfh5.currentNum); //这里获取的就是进度
},
// 添加水印
addWarker(url, warkerName) {
url = '自己输入pdf地址'
warkerName = '水印文字'
let that = this;
changeBlob().then((res) => {
res.arrayBuffer().then((rel) => {
// 获取arrauBuffer文件
viewmodifyPdf(rel);
});
});
//地址转文件
function changeBlob() {
return new Promise((resolve) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onload = () => {
if (xhr.status === 200) {
resolve(xhr.response);
}
};
xhr.send();
});
}
// 预览水印文件
async function viewmodifyPdf(file) {
// 将arrayBuff文件加载pdf文件
const pdfDoc = await PDFDocument.load(file);
// 引入自定义字体
let url = require("./font/Alibaba_PuHuiTi_2.0_55_Regular_85_Bold.ttf");
const fontBytes = await fetch(url).then((res) => res.arrayBuffer());
// 自定义字体挂载
pdfDoc.registerFontkit(fontkit);
const customFont = await pdfDoc.embedFont(fontBytes);
// 获取文档所有页
const pages = pdfDoc.getPages();
// 文字渲染配置
for (let i = 0; i < pages.length; i++) {
const noPage = pages[i];
const {
width,
height
} = noPage.getSize();
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 3; j++) {
noPage.drawText(warkerName, {
x: 230 * j,
y: (height / 4) * i,
size: 16,
font: customFont, //这里使用的是自定义字体
color: rgb(0.46, 0.53, 0.6),
rotate: degrees(-45),
opacity: 0.3,
});
}
}
}
// 获取水印文件
const pdfBytes = await pdfDoc.save();
let blobData = new Blob([pdfBytes], {
type: "application/pdf;Base64"
});
that.url = window.URL.createObjectURL(blobData) + "#toolbar=0";
that.pdfh5 = new Pdfh5("#demo", {
pdfurl: that.url,
});
}
},
downPdf() {
this.pdfh5.download("test");
},
},
};
</script>
<style lang="scss" scoped>
.pdf {
width: 400px;
height: 500px;
}
// 因为是禁止下载 所以页面也不允许右击保存
img {
pointer-events: none;
}
* {
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
</style><style>
/* 解决pdfh5内部图片太大的问题 */
.pdfjs .pdfViewer {
position: relative;
top: 0;
left: 0;
width: 100% !important;
padding: 10px 8px;
}
.pdfjs .pdfViewer .pageContainer {
width: 100% !important;
margin: 0px auto 8px auto;
position: relative;
overflow: visible;
-webkit-box-shadow: darkgrey 0px 1px 3px 0px;
-moz-box-shadow: darkgrey 0px 1px 3px 0px;
box-shadow: darkgrey 0px 1px 3px 0px;
background-color: white;
box-sizing: border-box;
}
.pdfjs .pdfViewer .pageContainer img {
width: 100% !important;
height: 100% !important;
position: relative;
z-index: 100;
pointer-events: none;
/* user-select:none; */
}
</style>
更多推荐
所有评论(0)