乐于分享
好东西不私藏

Vue3 + Print.js 实现 PDF 加水印打印输出实战教程

Vue3 + Print.js 实现 PDF 加水印打印输出实战教程

在日常开发中,PDF 文件添加水印后打印 / 导出是非常常见的需求(如合同水印、文件保密标识、企业 logo 水印等)。本文将手把手教你基于 Vue3 + Print.js 实现PDF 文件加载、自定义水印添加、一键打印 / 导出 PDF的完整功能,代码可直接复用。

一、方案选型与核心思路

1. 技术选型

  • Vue3:主流前端框架,组合式 API 开发更简洁

  • Print.js:轻量级前端打印库,支持 PDF、HTML、图片打印,无需后端介入

  • 原生 Canvas:给 PDF 页面绘制水印(文字 / 图片水印都支持)

  • pdfjs-dist:解析 PDF 文件,渲染到 Canvas(Print.js 依赖,无需额外配置)

2. 核心实现思路
  • 加载远程 / 本地 PDF 文件,解析为页面 Canvas
  • 通过 Canvas API 给每一页 PDF 绘制自定义水印(文字、透明度、角度、间距)
  • 将加水印后的 Canvas 渲染为打印区域
  • 调用 Print.js 实现水印 PDF 的打印 / 导出
二、环境搭建与依赖安装
1. 创建 Vue3 项目(已有项目可跳过)
# 创建vue3项目npm create vue@latest# 进入项目cd vue3-print-pdf-watermark# 安装依赖npm install

2. 安装核心依赖

# 安装打印库npm install print-js# 安装PDF解析依赖(必装,否则无法解析PDF)npm install pdfjs-dist

三、完整代码实现

1. 封装 PDF 水印打印工具函数

新建utils/pdfWatermarkPrint.js,封装通用水印绘制 + 打印逻辑:
import printJS from 'print-js'import * as pdfjsLib from 'pdfjs-dist'// 配置PDF.js worker(必须配置,否则解析失败)import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker/** * 给PDF添加水印并打印 * @param {StringpdfUrl - PDF文件地址(本地/远程) * @param {ObjectwatermarkConfig - 水印配置 */export async function printPdfWithWatermark(pdfUrl, watermarkConfig) {  // 默认水印配置  const defaultConfig = {    text'公司机密 请勿外泄'// 水印文字    fontSize16// 字体大小    color'rgba(150,150,150,0.3)'// 水印颜色+透明度    angle: -45// 旋转角度    xSpacing200// 水平间距    ySpacing150// 垂直间距  }  const config = { ...defaultConfig, ...watermarkConfig }  const pdfDoc = await pdfjsLib.getDocument(pdfUrl).promise  const numPages = pdfDoc.numPages  const pages = []  // 遍历渲染每一页PDF + 绘制水印  for (let i = 1; i <= numPages; i++) {    const page = await pdfDoc.getPage(i)    const viewport = page.getViewport({ scale1.5 })    // 创建Canvas    const canvas = document.createElement('canvas')    const ctx = canvas.getContext('2d')    canvas.width = viewport.width    canvas.height = viewport.height    // 渲染PDF到Canvas    await page.render({ canvasContext: ctx, viewport }).promise    // ========== 核心:绘制水印 ==========    ctx.save()    ctx.fillStyle = config.color    ctx.font = `${config.fontSize}px Arial`    ctx.rotate((config.angle * Math.PI) / 180)    // 循环铺满水印    for (let x = 0; x < canvas.width * 2; x += config.xSpacing) {      for (let y = 0; y < canvas.height * 2; y += config.ySpacing) {        ctx.fillText(config.text, x, y)      }    }    ctx.restore()    // 转为图片存入数组    pages.push(canvas.toDataURL('image/jpeg'1.0))  }  // 调用Print.js打印  printJS({    printable: pages,    type'image',    documentTitle'水印PDF文档',    imageStyle'width:100%;margin:0 auto;',  })}

2. Vue3 页面使用

在 Vue3 组件中直接调用工具函数,支持自定义水印文字、样式、间距
<template>  <divclass="pdf-print-container">    <h2>Vue3+Print.js PDF加水印打印</h2>    <!-- 自定义水印配置 -->    <divclass="config-group">      <inputv-model="watermarkText"placeholder="请输入水印文字" />      <button @click="handlePrint"class="print-btn">        加水印并打印PDF      </button>    </div>  </div></template><scriptsetup>import { ref } from 'vue'import { printPdfWithWatermark } from '@/utils/pdfWatermarkPrint'// 水印文字const watermarkText = ref('Vue3+Print.js 水印测试')// 打印处理函数const handlePrint = async () => {  try {    // 替换为你的PDF地址(本地/public目录或远程链接)    const pdfUrl = '/test.pdf'    await printPdfWithWatermark(pdfUrl, {      text: watermarkText.value,      fontSize18,      color'rgba(180,180,180,0.25)',      angle: -30,      xSpacing220,      ySpacing180,    })  } catch (error) {    console.error('PDF水印打印失败:', error)    alert('打印失败,请检查PDF文件是否可访问')  }}</script><stylescoped>.pdf-print-container {  max-width800px;  margin50px auto;  text-align: center;}.config-group {  margin-top30px;}input {  width300px;  padding8px 12px;  margin-right10px;}.print-btn {  padding8px 20px;  background#409eff;  color#fff;  border: none;  border-radius4px;  cursor: pointer;}</style>

四、关键配置说明

1. 水印配置项

参数
说明
默认值
text
水印文字内容
公司机密 请勿外泄
fontSize
水印字体大小
16px
color
水印颜色 + 透明度
rgba(150,150,150,0.3)
angle
水印旋转角度
-45°
xSpacing
水印水平间距
200px
ySpacing
水印垂直间距
150px

2. Print.js 核心参数

printJS({  printable: pages, // 打印内容(图片数组)  type'image'// 打印类型  documentTitle: '水印PDF文档'// 文档标题  imageStyle: 'width:100%'// 图片样式})

五、常见问题解决方案

1. PDF 跨域问题

现象:控制台报跨域错误,无法加载 PDF解决方案

后端配置 CORS 跨域允许

将 PDF 放入 Vue 项目public目录,使用本地路径访问

代理服务器转发 PDF 请求

2. PDF 解析失败 / 空白

解决方案

确保安装了pdfjs-dist

正确配置pdf.worker.entry

检查 PDF 文件是否损坏、路径是否正确

3. 水印不清晰 / 重叠

解决方案

调大scale参数(建议 1.5~2.0)

调整xSpacing/ySpacing间距

降低水印透明度rgba最后一位值

六、功能扩展

1. 支持图片水印

在 Canvas 绘制水印部分,替换为图片绘制:
// 图片水印const img = new Image()img.src = '水印图片地址'img.onload = () => {  ctx.drawImage(img, x, y, 100100)}

2. 导出 PDF 文件(不直接打印)

结合jsPDF库,可将加水印后的图片直接导出为 PDF 文件。

七、总结

本文实现了纯前端完成 PDF 加水印 + 打印的完整方案,无需后端参与,开箱即用:

基于 Vue3+Print.js 实现轻量打印

Canvas 绘制全屏自定义水印

支持多页 PDF、动态水印配置

解决跨域、解析失败等常见问题

该方案适用于合同、报表、公文等需要添加水印保护的 PDF 打印场景,代码简洁、扩展性强,可直接应用于企业项目。