掌握iText:轻松处理PDF文档-高级篇-添加水印

在这里插入图片描述
在这里插入图片描述

前言

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=zPdfContentByte 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.4fgs.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();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/217393.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Apollo】ubuntu20.04源码安装apollo8.0

官方源码安装教程 https://blog.csdn.net/weixin_45929038/article/details/120113008 安装NVIDIA GPU驱动 Apollo 8.0 的一些模块的编译和运行需要依赖 NVIDIA GPU 环境&#xff08;例如感知模块&#xff09;&#xff0c;如果有编译和运行这类模块的需求&#xff0c;则需要安…

蓝桥杯第一场强者挑战赛(C)SOSdp

之前在cf上面接触过SOSdp&#xff08;子集dp&#xff09;&#xff0c;这里就碰到了。 思路&#xff1a; 异或运算即非进位加法运算&#xff0c;因此如果需要进位的话&#xff0c;那么就无法满足题意&#xff0c;因此条件弱化为不需要进位&#xff0c;也就是不存在同一位上面都是…

多维时序 | Matlab实现GA-LSTM-Attention遗传算法优化长短期记忆神经网络融合注意力机制多变量时间序列预测

多维时序 | MATLAB实现BWO-CNN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现BWO-CNN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | Matlab实…

Dubbo 的 go 语言实现迎来了 Dubbo3 版本

新版本的 dubbo-go: 全面升级 Triple 协议,兼容 gRPC、标准 HTTP 客户端,提供简单明了的 API 用于编写 RPC server 与 client,解决组件间的基本通信问题。 针对微服务场景,提供了完善的服务治理能力,这包括配置管理、可观测性、流量管控规则、生态集成与适配等的全面升级…

基于Python+WaveNet+MFCC+Tensorflow智能方言分类—深度学习算法应用(含全部工程源码)(一)

目录 前言引言总体设计系统整体结构图系统流程图 运行环境Python环境TensorFlow 环境Jupyter Notebook环境Pycharm 环境 相关其它博客工程源代码下载其它资料下载 前言 博主前段时间发布了一篇有关方言识别和分类模型训练的博客&#xff0c;在读者的反馈中发现许多小伙伴对方言…

Kubernetes(k8s)集群部署----->超详细

Kubernetes&#xff08;k8s&#xff09;集群部署-----&#xff1e;超详细 一、资源准备二、安装准备2.1 主机环境设置2.1.1 关闭操作系统防火墙、selinux2.1.2 关闭swap交换分区2.1.3 允许iptables检测桥接流量&#xff08;可选&#xff09; 2.2 安装Docker环境2.3 安装Kubeadm…

idea__SpringBoot微服务10——整合JDBC(新依赖)

整合JDBC 完整项目地址&#xff1a;一、创建一个项目二、idea配置连接mysql三、创建yaml数据库连接配置文件四、测试一下&#xff0c;没有问题五、增删改查————————创作不易&#xff0c;如觉不错&#xff0c;随手点赞&#xff0c;关注&#xff0c;收藏(*&#xffe3;︶…

CS110L 系统编程安全 笔记

用户向程序输入数据&#xff0c;程序分析数据&#xff0c;但是当用户的输入大于缓冲区长度时&#xff0c;数据会溢出&#xff0c;覆盖掉内存中其他内容&#xff0c;比如函数返回地址&#xff0c;从而可能导致程序返回到错误的地址执行了不安全的程序&#xff08;远程代码执行&a…

MySQL笔记-第10章_创建和管理表

视频链接&#xff1a;【MySQL数据库入门到大牛&#xff0c;mysql安装到优化&#xff0c;百科全书级&#xff0c;全网天花板】 文章目录 第10章_创建和管理表1. 基础知识1.1 一条数据存储的过程1.2 标识符命名规则1.3 MySQL中的数据类型 2. 创建和管理数据库2.1 创建数据库2.2 使…

Xcode编译速度慢是什么原因?如何提高编译速度?

Hello各位伙伴们好&#xff0c;我是咕噜铁蛋&#xff01;作为一个开发者&#xff0c;我们都希望能够高效地开发应用程序&#xff0c;而编译速度是影响开发效率的重要因素之一。然而&#xff0c;有时候我们会发现在使用 Xcode 进行开发时&#xff0c;编译速度非常慢&#xff0c;…

模块一——双指针:11.盛最多水的容器

文章目录 题目解析算法原理解法一&#xff1a;暴力枚举(超时&#xff09;解法二&#xff1a;双指针单调性 代码实现暴力枚举(超时&#xff09;双指针单调性(时间复杂度为O(N)&#xff0c;空间复杂度为O(1)&#xff09; 题目解析 题目链接&#xff1a;11.盛最多水的容器 这道题…

C++的移动语义和完美转发

参考《现代C语言核心特性解析》 移动语义 C11新特性的std::move()用于将一个左值转换为右值引用。它并不是实际移动或复制数据&#xff0c;而是通过将一个左值强制转换为一个右值引用来实现对对象的转移。这个特性在C11中引入&#xff0c;用于优化对象移动操作的效率。 我们…

万界星空科技电子装配行业MES解决方案

电子电器装配属于劳动密集型、科技含量较高的行业&#xff0c;产品零部件种类繁多&#xff0c;生产组装困难&#xff0c;生产过程存在盲点&#xff0c;同时也决定了生产流水线多且对自动化水平要求较高。 万界星空科技提供的电子行业MES解决方案&#xff0c;提供从仓储管理、生…

pytorch——房价预测

1、首先对数据进行读取和预处理 2、读取数据后&#xff0c;对x数据进行标准化处理&#xff0c;以便于后续训练的稳定性&#xff0c;并转换为tensor格式 3、接下来设置训练参数和模型 这里采用回归模型&#xff0c;既yx*weight1bias1&#xff0c;设置的学习率为0.0006&#x…

perl脚本中使用eval函数执行可能有异常的操作

perl脚本中有时候执行的操作可能会引发异常&#xff0c;为了直观的说明&#xff0c;这里举一个json反序列化的例子&#xff0c;脚本如下&#xff1a; #! /usr/bin/perl use v5.14; use JSON; use Data::Dumper;# 读取json字符串数据 my $json_str join(, <DATA>); # 反…

《地理信息系统原理》笔记/期末复习资料(12. 地理信息工程)

目录 12. 地理信息工程 12.1. 地理信息系统工程的概念 12.2. 地理信息系统工程建设过程 12.2.1. 应用型地理信息系统设计步骤和方法 12.2.2. 需求分析 12.2.3. 系统设计 12.2.4. 系统开发与实施 12.2.5. 系统的评价和维护 12.3. GIS标准 12.4. 习题 12. 地理信息工程…

CNN、LeNet、AlexNet基于MNIST数据集进行训练和测试,并可视化对比结果

完成内容&#xff1a; 构建CNN并基于MNIST数据集进行训练和测试构建LeNet并基于MNIST数据集进行训练和测试构建AlexNet并基于MNIST数据集进行训练和测试对比了不同网络在MNIST数据集上训练的效果 准备工作 import torch import torch.nn as nn import torch.optim as optim …

高通SDX12:nand flash适配

一、SBL阶段 代码流程如下: boot_images\core\storage\flash\src\dal\flash_nand_init.c nand_probe ->nand_intialize_primary_hal_device ->>nand_get_device_list_supportedboot_images\core\storage\flash\src\dal\flash_nand_config.c ->>>flash_n…

ue4 解决角度万向锁的问题 蓝图节点

问题&#xff1a;当角度值从359-1变化的时候&#xff0c;数值会经历358、357… 解决方法&#xff1a;勾上Shortest Path&#xff0c;角度值的会从359-1

Kubernetes实战(十三)-使用kube-bench检测Kubernetes集群安全

1 概述 在当今云原生应用的开发中&#xff0c;Kubernetes已经成为标准&#xff0c;然而&#xff0c;随着其使用的普及&#xff0c;也带来了安全问题的挑战。本文将介绍如何使用kube-bench工具来评估和增强Kubernetes集群的安全性。 2 CIS (Center for Internet Security)简介…