You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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的页面渲染逻辑,在页面绘制完成后自动添加水印:

  1. 找到viewer.js中PageView的renderComplete回调函数(不同版本的PDF.js位置可能略有差异,可搜索关键词renderComplete定位)
  2. 在回调函数末尾添加以下水印绘制代码:
// 原有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 16:29:57