最近在做项目,遇到了PDF安全问题。需要为PDF添加水印,于是在网上各种搜各种试,然后下面的代码直接复制粘贴就ok。
1.POM文件
<!--为PDF加水印依赖 start-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
2.复制工具类到项目
package com.example.Watermark;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import javax.swing.*;
import java.awt.*;
import java.io.FileOutputStream;
/**
* @Cimpany yuJ.wang
* @ClassName: Demo
* @Description: 测试类
* @Date: 2023/3/13 8:53
* @Author: Administrator
*/
public class PdfUtils {
// 这是我自己用的参数
private static float opacity = 0.2f;
private int fontSize = 18;
private int angle = 30;
private float highDensity = 8;
private float widthDensity = 2;
/**
* @Description: 注意 inputFile != outputFile
* * @Param inputFile: 需要添加的水印文件
* @Param outputFile: 添加水印后的文件
* @Param watermark: 水印
* @Param opacity: 透明度设置
* @Param fontSize: 字体带线啊哦
* @Param angle: 水印倾斜角度
* @Param highDensity: 水印高密度 数字越大水印越少
* @Param widthDensity: 水印高宽密度 数字越大水印越少
* @return: void
* @Author: laoWangTou
* @Date: 2023/3/13
*/
public static void addWaterMark(String inputFile, String outputFile,String watermark,float opacity, int fontSize, int angle, int highDensity, int widthDensity){
PdfReader reader = null;
PdfStamper stamper = null;
try {
reader = new PdfReader(inputFile);
stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
/*
BaseFont.createFont() 是iText PDF库中用于创建字体对象的方法之一。
fontname: 字体的名称,可以是本地系统中已安装的字体名称,也可以是字体文件的路径。如果是字体文件的路径,需要使用相对路径或绝对路径指定。
encoding: 字符编码,例如BaseFont.IDENTITY_H,BaseFont.WINANSI等。
embedded:是否将字体嵌入PDF文档中,以确保在不同计算机上查看PDF文档时字体显示的一致性。如果设为true,则字体将被嵌入到PDF文档中。
*/
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.EMBEDDED);
Rectangle pageRect = null;
PdfGState gs = new PdfGState();
gs.setFillOpacity(opacity);
gs.setStrokeOpacity(0.2f);
//PDF共页数
int total = reader.getNumberOfPages() + 1;
JLabel label = new JLabel();
FontMetrics metrics;
int textH = 0;
int textW = 0;
label.setText(watermark);
metrics = label.getFontMetrics(label.getFont());
textH = metrics.getHeight();
textW = metrics.stringWidth(label.getText());
PdfContentByte under;
//PDF页循环
for (int i = 1; i < total; i++) {
//getPageSizeWithRotation 是一个计算 PDF 页面大小和旋转角度的函数,通常用于 PDF 文件处理和转换。
pageRect = reader.getPageSizeWithRotation(i);
under = stamper.getOverContent(i);
under.saveState();
under.setGState(gs);
under.beginText();
under.setFontAndSize(base, fontSize);
for (int height = textH; height < pageRect.getHeight()*2; height = height + textH * highDensity) {
for (int width = textW; width < pageRect.getWidth()*1.5 + textW; width = width + textW * widthDensity) {
under.showTextAligned(Element.ALIGN_LEFT, watermark, width - textW, height - textH, angle);
}
}
//添加水印文字
under.endText();
}
System.out.println("PDF添加水印成功!");
} catch (Exception e) {
e.printStackTrace();
System.out.println("PDF添加水印失败!");
}finally {
if (stamper != null) {
try {
stamper.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (reader != null) {
reader.close();
}
}
}
public static void main(String[] args) throws Exception{
String inputFile= "D:\\test\\1\\合同书.pdf"; //需要添加水印的文件
String outputFile= "D:\\test\\1\\合同书水印.pdf"; //添加完水印的文件存放路径
String waterMarkName="测试水印"; //需要添加的水印文字
float opacity=0.2f;
int fontsize=18;
int angle=30;
int highDensity=10;
int widthDensity=5;
long l = System.currentTimeMillis();
addWaterMark(inputFile,outputFile,waterMarkName,opacity,fontsize,angle,highDensity,widthDensity);
}
}
要注意工具类中inputFile , outputFile 不能相同。 如果在实际项目中涉及到需要生成的水印PDF替换原PDF。在调用addwaterMark()方法后,添加下方代码。
//水印后的文件
File file=new File(outputFile);
//删除原文件
File oldFile = new File(inputFile);
oldFile.delete();
if (file.renameTo(oldFile)) {
System.out.println("修改成功!");
}