使用pdfh5在线预览PDF并且加上文字水印
介绍如何使用pdfh5插件在Vue项目中实现PDF在线预览功能,并添加自定义文字水印
5 min read
前言
在前端开发中,经常需要在线预览 PDF 文件,并为 PDF 添加水印以保护文档版权。本文将介绍如何使用 pdfh5 插件实现这一功能。
参考文档:pdfh5 - npm
一、安装 pdfh5 插件
首先安装 pdfh5 插件:
bashnpm install pdfh5
二、使用 pdfh5 预览 PDF
完整代码实现
以下是使用 pdfh5 插件预览 PDF 并添加水印的完整 Vue 组件代码:
vue<template>
<div class="m-pdf">
<div class="pdfImg"></div>
</div>
</template>
<script>
import pdfjs from 'pdfh5/js/pdf';
import pdfWorker from 'pdfh5/js/pdf.worker';
pdfjs.GlobalWorkerOptions.workerSrc = pdfWorker;
export default {
name: 'Pdfh5',
data() {
return {
pdfh5: null,
fileUrl: '' // 如果引入本地pdf文件,需要将pdf放在public文件夹下,引用时使用绝对路径(/:表示public文件夹)
};
},
mounted() {
this.fileUrl = decodeURIComponent(this.$route.query.fileUrl);
this.pdfInit(this.fileUrl);
},
methods: {
async pdfInit(pdfUrl) {
try {
const pdfDoc = await pdfjs.getDocument(pdfUrl).promise;
const totalPage = pdfDoc.numPages;
for (let i = 1; i <= totalPage; i++) {
const page = await pdfDoc.getPage(i);
let scaledViewport = page.getViewport({ scale: 1.5 });
let canvas = document.createElement('canvas');
canvas.height = scaledViewport.height;
canvas.width = scaledViewport.width;
const listIndex = +document.querySelector('.pdfImg').childNodes.length;
canvas.className = 'img-item';
canvas.setAttribute('data-pdf-index', listIndex);
canvas.style.width = '100%';
let context = canvas.getContext('2d');
let renderContext = {
canvasContext: context,
viewport: scaledViewport
};
await page.render(renderContext);
// 这个方法是加水印的
const canvasFillStyle = context.createPattern(this.initWatermark(), 'repeat');
context.rect(0, 0, scaledViewport.width, scaledViewport.height);
context.fillStyle = canvasFillStyle;
context.fill();
canvas.remove();
document.querySelector('.pdfImg').appendChild(canvas);
}
return [];
} catch (error) {
return error;
}
},
initWatermark() {
let canvas = document.createElement('canvas');
canvas.width = 460;
canvas.height = 240;
let ctx = canvas.getContext('2d');
ctx.font = '36px Vedana';
ctx.fillStyle = 'rgba(200, 200, 200, 0.4)';
ctx.textAlign = 'left';
ctx.textBaseline = 'middle';
ctx.rotate((-18 * Math.PI) / 80);
ctx.fillText('水印水印水印水印水印', 0, 260);
return canvas;
}
}
};
</script>
<style lang="less" scoped>
.m-pdf {
// 保证pdf区域铺满整个屏幕
// 方法1:使用vw和vh视窗单位,1vw=视窗宽度的1%;1vh=视窗高度的1%
// width: 100vw;
// height: 100vh;
// 方法2:使用fixed定位
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
.header-bg {
background: #fff;
.title {
margin: auto;
padding: 10px 0px 0px 0px;
font-weight: 600;
font-size: 40rpx;
font-family: PingFangHK-Semibold, PingFangHK;
font-weight: 600;
color: #333333;
line-height: 56rpx;
}
}
}
</style>
三、核心功能说明
1. PDF 文档加载
使用 pdfjs.getDocument() 方法加载 PDF 文档:
javascriptconst pdfDoc = await pdfjs.getDocument(pdfUrl).promise;
const totalPage = pdfDoc.numPages;
2. 页面渲染
遍历每一页进行渲染,使用 Canvas 绘制:
javascriptfor (let i = 1; i <= totalPage; i++) {
const page = await pdfDoc.getPage(i);
let scaledViewport = page.getViewport({ scale: 1.5 });
// 创建canvas并渲染
}
3. 水印添加
通过 initWatermark() 方法创建水印图案,然后使用 createPattern() 将水印应用到整个 PDF 页面:
javascriptconst canvasFillStyle = context.createPattern(this.initWatermark(), 'repeat');
context.rect(0, 0, scaledViewport.width, scaledViewport.height);
context.fillStyle = canvasFillStyle;
context.fill();
4. 水印自定义
可以在 initWatermark() 方法中自定义水印的样式:
- 字体大小:
ctx.font = '36px Vedana' - 颜色透明度:
ctx.fillStyle = 'rgba(200, 200, 200, 0.4)' - 旋转角度:
ctx.rotate((-18 * Math.PI) / 80) - 水印文字:
ctx.fillText('水印水印水印水印水印', 0, 260)
四、注意事项
-
本地文件引用:如果引入本地 PDF 文件,需要将 PDF 放在
public文件夹下,引用时使用绝对路径(/表示public文件夹) -
线上地址:测试时需要使用线上地址,本地地址可能无法正常加载
-
跨域问题:确保 PDF 文件的服务器支持跨域访问
五、总结
通过 pdfh5 插件,我们可以轻松实现 PDF 在线预览功能,并通过 Canvas API 为 PDF 添加自定义水印。这种方式不仅简单高效,而且可以灵活定制水印样式,适合各种业务场景。