HTML如何给PDF页面加水印
在网页开发中经常需要将HTML内容导出为带水印的PDF文件,用于文档保护和版权标识。本文详细介绍了如何结合html2canvas和jspdf这两个前端库实现这一功能。通过html2canvas将目标HTML区域转换为Canvas画布,然后在画布上绘制自定义的水印文字,包括设置水印的文字内容、旋转角度、透明度、重复间距等样式,最后使用jspdf将处理好的图像数据生成为PDF文件并自动下载。教程提供了完整的可运行代码示例,涵盖了从库的引入、水印绘制到PDF导出的全部步骤,并说明了如何处理跨域图片、提高导出清晰度、自动分页等常见问题,帮助开发者快速掌握为网页内容添加水印并导出PDF的实用技能。
实现原理说明
整个流程分为三个核心步骤:
- 第一步:使用html2canvas库将目标HTML区域渲染为Canvas画布,把页面DOM结构转换为图像数据
- 第二步:在Canvas画布上绘制水印内容,水印可以自定义文字、颜色、透明度、旋转角度等样式
- 第三步:使用jspdf库将添加了水印的Canvas图像数据导出为PDF文件,支持自定义PDF的页面尺寸、方向等参数
前置依赖引入
我们需要在HTML页面中引入两个核心库的CDN资源,也可以根据项目需求通过npm安装后引入:
<!-- 引入html2canvas,用于将HTML转为Canvas --> <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script> <!-- 引入jspdf,用于生成PDF文件 --> <script src="https://cdn.jsdelivr.net/npm/jspdf@2.5.1/dist/jspdf.umd.min.js"></script>
完整实现代码
下面的代码实现了将指定id为content的HTML区域内容导出为带文字水印的PDF文件,你可以直接复制到本地HTML文件中运行测试:
// 导出PDF并添加水印的核心函数
function exportPdfWithWatermark() {
// 获取需要导出为PDF的HTML容器
const content = document.getElementById('content');
// 配置html2canvas的参数,保证渲染清晰度
const canvasOptions = {
scale: 2, // 缩放倍数,提升导出图像的清晰度
useCORS: true, // 允许加载跨域图片
backgroundColor: '#ffffff' // 设置背景色为白色,避免透明背景问题
};
// 第一步:将HTML内容渲染为Canvas
html2canvas(content, canvasOptions).then(canvas => {
// 第二步:在Canvas上绘制水印
const ctx = canvas.getContext('2d');
// 设置水印样式
ctx.font = '24px Microsoft YaHei'; // 水印字体和大小
ctx.fillStyle = 'rgba(200, 200, 200, 0.5)'; // 水印颜色,最后一个参数是透明度
ctx.rotate(-20 * Math.PI / 180); // 水印旋转角度,这里设置为逆时针20度
// 计算水印的重复间距,让水印铺满整个Canvas
const watermarkText = '内部文档 禁止外传';
const textWidth = ctx.measureText(watermarkText).width;
const gapX = textWidth + 100; // 水平方向水印间距
const gapY = 100; // 垂直方向水印间距
// 循环绘制水印,铺满整个Canvas区域
for (let x = -canvas.width; x < canvas.width * 2; x += gapX) {
for (let y = -canvas.height; y < canvas.height * 2; y += gapY) {
ctx.fillText(watermarkText, x, y);
}
}
// 第三步:将添加水印后的Canvas转为PDF
const imgData = canvas.toDataURL('image/jpeg', 0.9); // 将Canvas转为JPEG格式的base64数据
const pdf = new jsPDF({
orientation: 'portrait', // 页面方向,portrait为竖版,landscape为横版
unit: 'mm', // 单位,毫米
format: 'a4' // 页面尺寸,A4纸
});
// 计算PDF页面的尺寸,适配图像比例
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = (canvas.height * pdfWidth) / canvas.width;
// 将图像添加到PDF的第一页
pdf.addImage(imgData, 'JPEG', 0, 0, pdfWidth, pdfHeight);
// 如果内容超过一页,自动分页添加后续页面
let heightLeft = pdfHeight - pdf.internal.pageSize.getHeight();
let position = 0;
while (heightLeft > 0) {
position = heightLeft - pdfHeight;
pdf.addPage();
pdf.addImage(imgData, 'JPEG', 0, position, pdfWidth, pdfHeight);
heightLeft -= pdf.internal.pageSize.getHeight();
}
// 保存PDF文件,自定义文件名
pdf.save('带水印的文档.pdf');
}).catch(error => {
console.error('导出PDF失败:', error);
alert('导出PDF失败,请重试');
});
}页面结构示例
配合上面的导出函数,我们需要准备一个包含目标内容和导出按钮的HTML结构:
<div id="content" style="padding: 20px; width: 800px; margin: 0 auto;">
<h2>这是需要导出为PDF的文档内容</h2>
<p>这里是文档的正文部分,可以包含文字、图片、表格等各种HTML元素。</p>
<p>当点击导出按钮时,这部分内容会被转换为Canvas,添加水印后生成PDF文件。</p>
<ul>
<li>列表项1:前端开发基础</li>
<li>列表项2:PDF生成方案</li>
<li>列表项3:水印自定义配置</li>
</ul>
</div>
<div style="text-align: center; margin-top: 20px;">
<button onclick="exportPdfWithWatermark()" style="padding: 10px 20px; font-size: 16px; cursor: pointer;">
导出带水印的PDF
</button>
</div>水印自定义配置说明
你可以根据需求调整水印的相关参数,常见的可配置项如下:
| 配置项 | 说明 | 示例值 |
|---|---|---|
| ctx.font | 水印文字的字体和大小 | '18px SimSun'(宋体18号) |
| ctx.fillStyle | 水印颜色和透明度 | 'rgba(150, 150, 150, 0.3)'(灰色,30%透明度) |
| ctx.rotate | 水印旋转角度 | -30 * Math.PI / 180(逆时针30度) |
| watermarkText | 水印文字内容 | '版权所有 违者必究' |
| gapX / gapY | 水印水平和垂直间距 | gapX=150,gapY=120 |
注意事项
- 如果HTML内容中包含跨域图片,需要确保图片服务器配置了允许跨域访问,或者将图片转为base64格式嵌入,否则html2canvas可能无法正确渲染图片
- Canvas的scale参数不建议设置过高,过高的缩放倍数会导致生成的图像数据过大,影响PDF导出速度和文件大小
- 如果导出的PDF内容模糊,可以适当提高scale参数,或者检查原始HTML内容的样式是否适配打印场景,避免使用过于特殊的CSS属性
- jspdf的addImage方法支持的图像格式为JPEG、PNG等,toDataURL时可以根据需求选择对应的格式和压缩质量