返回文章列表

使用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>

&lt;style lang="less" scoped&gt;
.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;
    }
  }
}
&lt;/style&gt;

三、核心功能说明

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)

四、注意事项

  1. 本地文件引用:如果引入本地 PDF 文件,需要将 PDF 放在 public 文件夹下,引用时使用绝对路径(/ 表示 public 文件夹)

  2. 线上地址:测试时需要使用线上地址,本地地址可能无法正常加载

  3. 跨域问题:确保 PDF 文件的服务器支持跨域访问

五、总结

通过 pdfh5 插件,我们可以轻松实现 PDF 在线预览功能,并通过 Canvas API 为 PDF 添加自定义水印。这种方式不仅简单高效,而且可以灵活定制水印样式,适合各种业务场景。