前言
iText作为一个功能强大、灵活且广泛应用的PDF处理工具,在实际项目中发挥着重要作用。通过这些文章,读者可以深入了解如何利用iText进行PDF的创建、编辑、加密和提取文本等操作,为日常开发工作提供了宝贵的参考和指导。
掌握iText:轻松处理PDF文档-基础篇
掌握iText:轻松处理PDF文档-进阶篇
需求描述
可能你会经常遇到类似的场景, 为了保护敏感信息和版权,需要在PDF文件上添加水印,在类似这样的需求上再作一个延伸,可能就是两种情况:第一种,程序在处理数据后,生成新的pdf文档的同时增加水印;第二种,pdf文档已经存在,需要在导出的时候,给已经存在的pdf文档增加水印。那么这两种需求,如果使用iText5,应该怎么实现呢?
iText的依赖
在maven的pom.xml中配置:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
生成新的pdf文档的同时增加水印
程序在处理数据后,生成新的pdf文档的同时增加水印,具体的步骤如下:
1.创建一个大小为A4纸、横向显示的PDF文档。
2.创建PdfWriter对象,用于将文档内容写入到PDF文件中。
3.打开文档。
4.创建第一页(可省略)。
5.获取水印的PdfContentByte对象。
6.调用setWaterMar方法,在水印画布上设置水印内容和样式。
7.循环100次,在文档中添加一段文字。
8.关闭文档和PdfWriter对象。
9.输出成功生成PDF文件的消息。
其中 setWaterMar 方法封装了具体的水印设置逻辑,具体逻辑如下:
1.检查水印画布是否为空。
2.开始设置水印文本。
3.设置水印的透明度。
4.创建PdfGState对象,设置填充字体的不透明度为0.4f。
5.设置水印的字体和大小。
6.设置水印的对齐方式、位置和旋转角度。
7.设置水印的颜色。
8.结束设置水印文本。
// 往pdf文档中写入文本内容时,添加水印
@Test
public void test() throws FileNotFoundException, DocumentException {
//实现A4纸页面 并且横向显示(不设置则为纵向)
Document document = new Document(PageSize.A4.rotate());
PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream("e:/pdf-test/test-v1.pdf"));
// 打开文档
document.open();
// 创建第一页(如果只有一页的话,这一步可以省略)
document.newPage();
// 加入水印,水印内容:x+y=z
PdfContentByte waterMar = pdfWriter.getDirectContentUnder();
this.setWaterMar(waterMar, "x+y=z");
for (int i = 0; i < 100; i++) {
// 加入文档内容
document.add(new Paragraph("my first pdf demo"));
}
// 关闭文档
document.close();
pdfWriter.close();
}
private void setWaterMar(PdfContentByte waterMar, String waterContent) {
if (waterMar == null) {
return;
}
// 开始设置水印
waterMar.beginText();
// 设置水印透明度
PdfGState gs = new PdfGState();
// 设置填充字体不透明度为0.4f
gs.setFillOpacity(0.4f);
try {
// 设置水印字体参数及大小(字体参数,字体编码格式,是否将字体信息嵌入到pdf中(一般不需要嵌入),字体大小)
waterMar.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 60);
// 设置透明度
waterMar.setGState(gs);
// 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度
waterMar.showTextAligned(Element.ALIGN_RIGHT, waterContent, 500, 430, 45);
// 设置水印颜色
waterMar.setColorFill(BaseColor.GRAY);
//结束设置
waterMar.endText();
waterMar.stroke();
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
效果如下:
给已经生成的pdf文档增加水印
1.指定输入和输出的 PDF 文件路径。
2.创建 PdfReader 对象,用于读取原始 PDF 文件。
3.创建 PdfStamper 对象,用于添加水印,并传入原始 PDF 文件和输出 PDF 文件的路径。
4.获取原始 PDF 文件的页数。
5.加载自定义字体 HongLeiXingShuJianTi-2.otf。我这里是从字体天下网(https://www.fonts.net.cn)下载一个字体,可以使用你拥有的其他字体,需要注意字体版权问题,我下载这个是商用免费。
6.设置水印的字体大小和旋转角度。
7.准备向每一页添加水印。
8.循环迭代每一页,获取当前页的 PdfContentByte 对象,即用于绘制内容的画布。
9.调用 setWaterMar 方法,在当前页的画布上添加水印。
10.关闭 PdfStamper 和 PdfReader 对象,释放资源。
11.输出一条成功添加水印的消息。
其中 setWaterMar 方法封装了具体的水印设置逻辑,具体逻辑如下:
1.设置水印的填充颜色为浅灰色。
2.开始绘制文本。
3.设置文本的字体和大小。
4.使用嵌套循环,将水印文本重复添加到当前页的多个位置上。
5.结束绘制文本。
@Test
public void test2() {
try {
// 输入PDF文件路径
String inputFile = "e:/pdf-test/test.pdf";
// 输出PDF文件路径
String outputFile = "e:/pdf-test/test-v2.pdf";
// 创建PdfReader对象读取原始PDF文件
PdfReader reader = new PdfReader(inputFile);
// 创建PdfStamper对象,用于添加水印
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
// 设置水印属性
int n = reader.getNumberOfPages();
URL resource = getClass().getClassLoader().getResource("HongLeiXingShuJianTi-2.otf");
FontFactory.register(resource.getPath(), "HongLeiXingShuJianTi-2.otf");
BaseFont baseFont = BaseFont.createFont("HongLeiXingShuJianTi-2.otf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
float fontSize = 20; // 设置字体大小
float watermarkAngle = 10; // 设置水印旋转角度
PdfContentByte watermark;
// 添加水印到每一页
for (int i = 1; i <= n; i++) {
watermark = stamper.getOverContent(i);
this.setWaterMar(watermark, "凡夫编程", baseFont, fontSize, watermarkAngle);
}
// 关闭PdfStamper和PdfReader对象
stamper.close();
reader.close();
System.out.println("水印已添加到PDF文档中。");
} catch (DocumentException | IOException e) {
e.printStackTrace();
}
}
private void setWaterMar(PdfContentByte watermark, String waterContent, BaseFont baseFont, float fontSize, float watermarkAngle) {
watermark.setColorFill(BaseColor.LIGHT_GRAY);
watermark.beginText();
watermark.setFontAndSize(baseFont, fontSize);
for (int m = 0; m < 10; m++) {
for (int n = 0; n < 10; n++) {
watermark.showTextAligned(Element.ALIGN_LEFT, "凡夫编程", 10 + m * 150, 10 + n * 100, watermarkAngle);
}
}
watermark.endText();
}
效果如下:
写入与读取元数据
写入元数据:
1.创建一个空白的PDF文档对象。
2.创建PdfWriter对象,用于将文档内容写入到PDF文件中,并指定输出文件路径。
3.打开文档。
4.向文档中添加一段文字内容。
5.使用addCreator方法设置文档的创建者信息。
6.使用addTitle方法设置文档的标题信息。
7.使用addAuthor方法设置文档的作者信息。
8.关闭文档。
@Test
public void test6() {
Document document = new Document();
try {
// 设置加密算法和用户/所有者密码
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("e:/pdf-test/test-v6.pdf"));
document.open();
// 添加一些内容到文档中
document.add(new Paragraph("This is pdf document."));
document.addCreator("fanfu");
document.addTitle("test-pdf");
document.addAuthor("gaoxing");
document.close();
} catch (DocumentException | IOException e) {
e.printStackTrace();
}
}
读取元数据:
1.创建一个PdfReader对象,用于读取指定PDF文件("e:/pdf-test/test-v6.pdf")的内容。
2.调用getInfo方法获取PDF文档的元数据信息,并将其存储在一个HashMap对象中。
3.使用for循环遍历HashMap中的键值对,打印每个键对应的值。
@Test
public void test7() {
try {
// 设置加密算法和用户/所有者密码
PdfReader pdfReader = new PdfReader(new FileInputStream("e:/pdf-test/test-v6.pdf"));
HashMap<String, String> info = pdfReader.getInfo();
for (String key : info.keySet()) {
System.out.println(info.get(key));
}
} catch (IOException e) {
e.printStackTrace();
}
}