使用 iText 库给PDF文件加水印
iText 库介绍
iText 是一款流行的 Java PDF 库,它可以用来创建、读取、修改和提取 PDF 内容。iText 提供了许多 API,包括添加文本水印的功能。
注释:创建一个Springboot来测试 iText的使用,创建项目不做过多介绍
需要的依赖
<!-- iText 是一款流行的 Java PDF 库-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
<!-- hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.8</version>
</dependency>
水印样式封装
创建 ITextAttributes 用于封装pdf水印样式
package com.test.testdemo.itext;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.BaseFont;
import lombok.Data;
import java.io.IOException;
/**
* @Author Chenry.r
* @Date 9/9/2023 下午10:11
* @Version 1.0
* @Description <p>备注:封装pdf水印样式</p>
*/
@Data
public class ITextAttributes {
//字体样式
private BaseFont fontStyle = BaseFont.createFont();
//字体大小
private float fontSize = 36f;
//字体颜色
private BaseColor fontColor = BaseColor.LIGHT_GRAY;
//水印位置
private int location = Element.ALIGN_CENTER;
//水印内容
private String showTxt = "Chenry.r制作,欢迎查看";
//坐标以及旋转角度
private float x = 300, y = 400, rotation = 45;
public ITextAttributes() throws DocumentException, IOException {
}
public ITextAttributes(BaseFont fontStyle, float fontSize, BaseColor fontColor, int location, String showTxt, float x, float y, float rotation) throws DocumentException, IOException {
this.fontStyle = fontStyle;
this.fontSize = fontSize;
this.fontColor = fontColor;
this.location = location;
this.showTxt = showTxt;
this.x = x;
this.y = y;
this.rotation = rotation;
}
}
封装工具类
创建 ItextWatermarkUtil 封装水印添加工具类
注意:这里你添加的水印如果有汉字的话可能要下载一个simsun.ttf
字体放到 resources\fonts\simsun.ttf目录下
下载:simsun.ttf(微软宋体)
链接: https://pan.baidu.com/s/1-a7rZp6NIO0jaFr4adIWEw 提取码: 45xd
package com.test.testdemo.util;
import cn.hutool.core.io.IoUtil;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.*;
import com.test.testdemo.itext.ITextAttributes;
import org.springframework.core.io.ClassPathResource;
import java.io.*;
/**
* @Author Chenry.r
* @Date 9/9/2023 下午10:16
* @Version 1.0
* @Description <p>备注:pdf添加水印工具类</p>
*/
public class ItextWatermarkUtil {
/**
* @param pdfPath: 要处理的pdf路径
* @param outPath: 输出pdf文件路径
* @param attributes:
* @Des: 这个方法处理不了中文水印, 可能因为我的
* @Author: Chenry.r
* @Date: 9/9/2023 下午11:07
*/
public static void addWaterMark1(String pdfPath, String outPath, ITextAttributes attributes) {
try {
System.out.println("--------------开始添加水印--------------------");
// 读取原始 PDF 文件
PdfReader reader = new PdfReader(pdfPath);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outPath));
// 获取 PDF 中的页数
int pageCount = reader.getNumberOfPages();
// 添加水印
for (int i = 1; i <= pageCount; i++) {
PdfContentByte contentByte = stamper.getUnderContent(i); // 或者 getOverContent()
contentByte.beginText();
contentByte.setFontAndSize(attributes.getFontStyle(), attributes.getFontSize());
contentByte.setColorFill(attributes.getFontColor());
contentByte.showTextAligned(attributes.getLocation(), attributes.getShowTxt(), attributes.getX(), attributes.getY(), attributes.getRotation());
contentByte.endText();
System.out.println("--------------已完成第" + (i) + "页的水印添加--------------------");
}
// 保存修改后的 PDF 文件并关闭文件流
stamper.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("--------------添加水印完成--------------------");
}
}
/**
* @param pdfPath: 要处理的pdf路径
* @param outPath: 输出pdf文件路径
* @param attributes:
* @Des: 处理带汉字的水印
* @Author: Chenry.r
* @Date: 9/9/2023 下午11:06
*/
public static void addWaterMark2(String pdfPath, String outPath, ITextAttributes attributes) {
try {
System.out.println("--------------开始添加水印--------------------");
// 读取原始 PDF 文件
PdfReader reader = new PdfReader(pdfPath);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outPath));
// 获取 PDF 中的页数
int pageCount = reader.getNumberOfPages();
// 添加水印
PdfContentByte content = null;
byte[] fontBytes = IoUtil.readBytes(new ClassPathResource("fonts/simsun.ttf").getInputStream());
for (int i = 1; i <= pageCount; i++) {
content = stamper.getOverContent(i);
content.beginText();
content.setFontAndSize(BaseFont.createFont("simsun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED, true, fontBytes, null), attributes.getFontSize());
content.setColorFill(attributes.getFontColor());
content.showTextAligned(attributes.getLocation(), attributes.getShowTxt(), attributes.getX(), attributes.getY(), attributes.getRotation());
content.endText();
System.out.println("--------------已完成第" + (i) + "页的水印添加--------------------");
}
// 保存修改后的 PDF 文件并关闭文件流
stamper.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("--------------添加水印完成--------------------");
}
}
/**
* @param inputStream: PDF输入流
* @param outputStream: PDF输出流
* @param watermark: 水印内容
* @Des: 使用流的形式给PDF文件添加水印
* @Author: Chenry.r
* @Date: 9/9/2023 下午11:17
*/
private static void addPdfWatermark(InputStream inputStream, OutputStream outputStream, String watermark) {
// 使用iText向PDF文件添加水印
try {
System.out.println("--------------开始添加水印--------------------");
PdfReader pdfReader = new PdfReader(inputStream);
PdfStamper stamper = new PdfStamper(pdfReader, outputStream);
int total = pdfReader.getNumberOfPages();
PdfContentByte content = null;
byte[] fontBytes = IoUtil.readBytes(new ClassPathResource("fonts/simsun.ttf").getInputStream());
PdfGState gs = new PdfGState();
for (int i = 1; i <= total; i++) {
content = stamper.getOverContent(i);
gs.setFillOpacity(0.3f);
content.setGState(gs);
content.beginText();
content.setColorFill(BaseColor.RED);
content.setFontAndSize(BaseFont.createFont("simsun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED, true, fontBytes, null), 30F);
content.showTextAligned(Element.ALIGN_CENTER, watermark, 300F, 400F, 45F);
content.endText();
}
stamper.close();
pdfReader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("--------------添加水印完成--------------------");
}
}
public static void main(String[] args) throws IOException, DocumentException {
// 测试addPdfWatermark方法
InputStream inputStream = new FileInputStream("D:\\Users\\ThisPc\\桌面\\我的文件\\量身定制版-Java基础面试题.pdf");
OutputStream outputStream = new FileOutputStream("D:\\Users\\ThisPc\\桌面\\新建文件夹\\量身定制版-Java基础面试题.pdf");
String watermark = "Chenry.r制作,欢迎查看2023年9月9日";
addPdfWatermark(inputStream, outputStream, watermark);
// 测试addWaterMark、addWaterMark2方法
//addWaterMark2("D:\\Users\\ThisPc\\桌面\\我的文件\\量身定制版-Java基础面试题.pdf", "D:\\Users\\ThisPc\\桌面\\新建文件夹\\量身定制版-Java基础面试题.pdf", new ITextAttributes());
}
}
内容笔记
1、在添加水印之前,需要读取原始 PDF 文件:
PdfReader reader = new PdfReader("original.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("output.pdf"));
2、然后,遍历 PDF 中的所有页面,并使用 PdfContentByte 添加水印:
// 获取 PDF 中的页数
int pageCount = reader.getNumberOfPages();
// 添加水印
for (int i = 1; i <= pageCount; i++) {
PdfContentByte contentByte = stamper.getUnderContent(i); // 或者 getOverContent()
contentByte.beginText();
contentByte.setFontAndSize(BaseFont.createFont(), 36f);
contentByte.setColorFill(BaseColor.LIGHT_GRAY);
contentByte.showTextAligned(Element.ALIGN_CENTER, "Watermark", 300, 400, 45);
contentByte.endText();
}
3、最后,需要保存修改后的 PDF 文件并关闭文件流:
stamper.close();
reader.close();
4、示例:
package com.test.testdemo.test;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @Author Chenry.r
* @Date 10/9/2023 上午12:47
* @Version 1.0
* @Description <p>备注:示例</p>
*/
public class ItextWatermark {
public static void main(String[] args) throws IOException, DocumentException {
// 读取原始 PDF 文件
PdfReader reader = new PdfReader("D:\\Users\\ThisPc\\桌面\\我的文件\\量身定制版-Java基础面试题.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("D:\\Users\\ThisPc\\桌面\\新建文件夹\\量身定制版-Java基础面试题-水印.pdf"));
// 获取 PDF 中的页数
int pageCount = reader.getNumberOfPages();
// 添加水印
for (int i = 1; i <= pageCount; i++) {
PdfContentByte contentByte = stamper.getUnderContent(i); // 或者 getOverContent()
contentByte.beginText();
contentByte.setFontAndSize(BaseFont.createFont(), 36f);
contentByte.setColorFill(BaseColor.LIGHT_GRAY);
contentByte.showTextAligned(Element.ALIGN_CENTER, "Watermark", 300, 400, 45);
contentByte.endText();
}
// 保存修改后的 PDF 文件并关闭文件流
stamper.close();
reader.close();
}
}