如何在PDF.js中添加预览水印?Java Web应用技术求助
在PDF.js中添加水印的正确实现方式
你遇到的报错是因为PDF.js官方API并没有pageView.setWatermark这个方法,下面提供两种可行的实现方案:
方案一:页面渲染完成后通过Canvas绘制水印(无需修改PDF.js源码)
这种方法通过监听PDF加载和渲染事件,在页面的Canvas上直接绘制水印,适合快速集成:
// 监听文档所有页面加载完成事件 document.addEventListener('pagesloaded', () => { // 获取所有页面容器 const pageElements = document.querySelectorAll('#viewer .page'); pageElements.forEach(pageEl => { // 获取页面对应的Canvas const canvas = pageEl.querySelector('.canvasWrapper canvas'); if (!canvas) return; const ctx = canvas.getContext('2d'); const watermarkConfig = { text: 'Confidential', fontSize: 20, color: 'rgba(0, 0, 0, 0.5)', angle: 45, spacing: 150 // 水印之间的间距,控制密度 }; // 设置水印样式 ctx.font = `${watermarkConfig.fontSize}px Arial`; ctx.fillStyle = watermarkConfig.color; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; const canvasWidth = canvas.width; const canvasHeight = canvas.height; // 保存当前画布状态,避免影响原有渲染 ctx.save(); // 平移到画布中心,旋转指定角度 ctx.translate(canvasWidth / 2, canvasHeight / 2); ctx.rotate((watermarkConfig.angle * Math.PI) / 180); // 循环绘制水印,铺满整个页面 for (let x = -canvasWidth / 2; x < canvasWidth / 2; x += watermarkConfig.spacing) { for (let y = -canvasHeight / 2; y < canvasHeight / 2; y += watermarkConfig.spacing) { ctx.fillText(watermarkConfig.text, x, y); } } // 恢复画布状态 ctx.restore(); }); }); // 监听页面缩放、翻页事件,重新绘制水印(避免水印丢失) document.addEventListener('zoom', () => { // 复用上面的绘制逻辑,或者封装成函数调用 }); document.addEventListener('pagerendered', () => { // 复用上面的绘制逻辑,或者封装成函数调用 });
方案二:修改PDF.js的viewer.js源码(全局自动生效)
如果需要所有预览的PDF都自动添加水印,可以修改viewer.js的页面渲染逻辑,在页面绘制完成后自动添加水印:
- 找到viewer.js中
PageView的renderComplete回调函数(不同版本的PDF.js位置可能略有差异,可搜索关键词renderComplete定位) - 在回调函数末尾添加以下水印绘制代码:
// 原有renderComplete逻辑之后添加 const canvas = this.canvas; const ctx = canvas.getContext('2d'); const watermarkText = 'Confidential'; const fontSize = 20; const opacity = 0.5; const angle = 45; const spacing = 150; ctx.font = `${fontSize}px Arial`; ctx.fillStyle = `rgba(0, 0, 0, ${opacity})`; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; const canvasWidth = canvas.width; const canvasHeight = canvas.height; ctx.save(); ctx.translate(canvasWidth / 2, canvasHeight / 2); ctx.rotate((angle * Math.PI) / 180); for (let x = -canvasWidth / 2; x < canvasWidth / 2; x += spacing) { for (let y = -canvasHeight / 2; y < canvasHeight / 2; y += spacing) { ctx.fillText(watermarkText, x, y); } } ctx.restore();
注意事项
- 方案一的优点是无需修改PDF.js源码,适配灵活;缺点是页面缩放、翻页后需要重新绘制水印,需额外监听对应事件。
- 方案二的优点是全局生效,页面重新渲染时自动添加水印;缺点是需要维护修改后的viewer.js,PDF.js版本升级时需要重新适配代码位置。
内容的提问来源于stack exchange,提问作者Ravindu Yasith
相关产品推荐
相关产品推荐

