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 依赖,无需额外配置)
-
加载远程 / 本地 PDF 文件,解析为页面 Canvas -
通过 Canvas API 给每一页 PDF 绘制自定义水印(文字、透明度、角度、间距) -
将加水印后的 Canvas 渲染为打印区域 -
调用 Print.js 实现水印 PDF 的打印 / 导出
# 创建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 水印打印工具函数
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 {String} pdfUrl - PDF文件地址(本地/远程)* @param {Object} watermarkConfig - 水印配置*/export async function printPdfWithWatermark(pdfUrl, watermarkConfig) {// 默认水印配置const defaultConfig = {text: '公司机密 请勿外泄', // 水印文字fontSize: 16, // 字体大小color: 'rgba(150,150,150,0.3)', // 水印颜色+透明度angle: -45, // 旋转角度xSpacing: 200, // 水平间距ySpacing: 150, // 垂直间距}const config = { ...defaultConfig, ...watermarkConfig }const pdfDoc = await pdfjsLib.getDocument(pdfUrl).promiseconst numPages = pdfDoc.numPagesconst pages = []// 遍历渲染每一页PDF + 绘制水印for (let i = 1; i <= numPages; i++) {const page = await pdfDoc.getPage(i)const viewport = page.getViewport({ scale: 1.5 })// 创建Canvasconst canvas = document.createElement('canvas')const ctx = canvas.getContext('2d')canvas.width = viewport.widthcanvas.height = viewport.height// 渲染PDF到Canvasawait page.render({ canvasContext: ctx, viewport }).promise// ========== 核心:绘制水印 ==========ctx.save()ctx.fillStyle = config.colorctx.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 页面使用
<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,fontSize: 18,color: 'rgba(180,180,180,0.25)',angle: -30,xSpacing: 220,ySpacing: 180,})} catch (error) {console.error('PDF水印打印失败:', error)alert('打印失败,请检查PDF文件是否可访问')}}</script><stylescoped>.pdf-print-container {max-width: 800px;margin: 50px auto;text-align: center;}.config-group {margin-top: 30px;}input {width: 300px;padding: 8px 12px;margin-right: 10px;}.print-btn {padding: 8px 20px;background: #409eff;color: #fff;border: none;border-radius: 4px;cursor: pointer;}</style>
四、关键配置说明
1. 水印配置项
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2. Print.js 核心参数
printJS({printable: pages, // 打印内容(图片数组)type: 'image', // 打印类型documentTitle: '水印PDF文档', // 文档标题imageStyle: 'width:100%', // 图片样式})
五、常见问题解决方案
1. PDF 跨域问题
后端配置 CORS 跨域允许
将 PDF 放入 Vue 项目public目录,使用本地路径访问
代理服务器转发 PDF 请求
2. PDF 解析失败 / 空白
确保安装了pdfjs-dist
正确配置pdf.worker.entry
检查 PDF 文件是否损坏、路径是否正确
3. 水印不清晰 / 重叠
调大scale参数(建议 1.5~2.0)
调整xSpacing/ySpacing间距
降低水印透明度rgba最后一位值
六、功能扩展
1. 支持图片水印
// 图片水印const img = new Image()img.src = '水印图片地址'img.onload = () => {ctx.drawImage(img, x, y, 100, 100)}
2. 导出 PDF 文件(不直接打印)
七、总结
基于 Vue3+Print.js 实现轻量打印
Canvas 绘制全屏自定义水印
支持多页 PDF、动态水印配置
解决跨域、解析失败等常见问题
夜雨聆风