当前位置: 首页 > news >正文

掌握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();}
}

相关文章:

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

前言 iText作为一个功能强大、灵活且广泛应用的PDF处理工具&#xff0c;在实际项目中发挥着重要作用。通过这些文章&#xff0c;读者可以深入了解如何利用iText进行PDF的创建、编辑、加密和提取文本等操作&#xff0c;为日常开发工作提供了宝贵的参考和指导。 掌握iText&…...

深度学习基本概念

1.全连接层 全连接层就是该层的所有节点与输入节点全部相连&#xff0c;如图所 示。假设输入节点为X1&#xff0c; X 2&#xff0c; X 3&#xff0c;输出节点为 Y 1&#xff0c; Y 2&#xff0c; Y 3&#xff0c; Y 4。令 矩阵 W 代表全连接层的权重&#xff0c; W 12也就代表 …...

2023年最详细的:本地Linux服务器安装宝塔面板,并内网穿透实现公网远程登录

&#x1f4da;&#x1f4da; &#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Linux》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一…...

基于ssm金旗帜文化培训学校网站的设计与开发论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对培训学校展示信息管理混乱&#xff0c;出错率高&#xff0c;信息安全…...

【Java】猜数字小游戏

规则 游戏开始随机生成4位数字符串&#xff0c;每个数字从0到9各不相同&#xff0c;比如0123玩家10次猜数机会&#xff0c;输入4位数字符串&#xff0c;每个数字从0到9各不相同游戏判断玩家输入与所猜谜底数&#xff0c;给出结果nAnB&#xff0c;A表示位置和数字都猜对的个数&…...

汽车EDI:Chrysler EDI项目案例

菲亚特克莱斯勒汽车Fiat Chrysler Automobiles(FCA)是一家全球性汽车制造商&#xff0c;主营产品包括轿车、SUV、皮卡车、商用车和豪华车等多种车型。其旗下品牌包括菲亚特、克莱斯勒、道奇、Jeep、Ram、阿尔法罗密欧和玛莎拉蒂等。 Chrysler通过EDI来优化订单处理、交付通知、…...

Locust:可能是一款最被低估的压测工具

01、Locust介绍 开源性能测试工具https://www.locust.io/&#xff0c;基于Python的性能压测工具&#xff0c;使用Python代码来定义用户行为&#xff0c;模拟百万计的并发用户访问。每个测试用户的行为由您定义&#xff0c;并且通过Web UI实时监控聚集过程。 压力发生器作为性能…...

用23种设计模式打造一个cocos creator的游戏框架----(十八)责任链模式

1、模式标准 模式名称&#xff1a;责任链模式 模式分类&#xff1a;行为型 模式意图&#xff1a;使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有一个对象处…...

100天精通风控建模(原理+Python实现)——第9天:风控建模中为什么需要特征工程?

风控模型已在各大银行和公司都实际运用于业务,用于营销和风险控制等。本文以视频的形式阐述风控建模中为什么需要特征工程。并提供风控建模原理和Python实现文章清单。    之前已经阐述了100天精通风控建模(原理+Python实现)——第1天:什么是风控建模?    100天精通风控…...

【PHP】计算某个特定时间戳距离现在的天数

在PHP中&#xff0c;你可以使用time()函数获取当前时间的时间戳&#xff0c;然后将它与你想要计算的过去或未来的时间戳进行比较。为了得到相差的天数&#xff0c;你需要先用两个时间戳相减得到秒数差&#xff0c;然后再除以一天的总秒数&#xff08;通常是86400秒&#xff09;…...

lv12 uboot移植深化 9

u-boot-2013.01移植 【实验目的】 了解u-boot 的代码结构及移植的基本方法 【实验环境】 ubuntu 14.04发行版FS4412实验平台交叉编译工具arm-none-linux-gnueabi- 【注意事项】 实验步骤中以“$”开头的命令表示在 ubuntu 环境下执行 【实验步骤】 1 建立自己的平台 1.…...

大数据与深度挖掘:如何在数字营销中与研究互动

数字营销最吸引人的部分之一是对数据的内在关注。 如果一种策略往往有积极的数据&#xff0c;那么它就更容易采用。同样&#xff0c;如果一种策略尚未得到证实&#xff0c;则很难获得支持进行测试。 数字营销人员建立数据信心的主要方式是通过研究。这些研究通常分为两类&…...

xtu oj 1327 字符矩阵

按照示例的规律输出字符矩阵。 比如输入字母D时&#xff0c;输出字符矩阵如下 ABCDCBA BBCDCBB CCCDCCC DDDDDDD CCCDCCC BBCDCBB ABCDCBA字符矩阵行首、尾都无空格。 输入 每行一个大写英文字母&#xff0c;如果字符为#&#xff0c;表示输入结束&#xff0c;不需要处理。 …...

讨论用于评估DREX的五种DR指标

概要 动态范围是已经使用了近一个世纪的用于评估接收机性能的参数。这里介绍五种动态有关指标的定义及测试方法&#xff0c;用于评估数字接收激励器&#xff08;DREX&#xff0c;digital receiver exciters&#xff09;。DREX是构成雷达的关键整部件&#xff0c;其瞬时带宽&am…...

基于SpringBoot的在线疫苗预防小程序

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SpringBoot的在线疫苗预防小程序,ja…...

Kafka使用总结

1、Kafka是何如做到高性能的&#xff1f; a、消息批处理减少网络通信开销&#xff0c;提升系统吞吐能力&#xff08;先攒一波&#xff0c;消息以“批”为单位进行处理&#xff09; 生产端&#xff1a;无论是同步发送还是异步发送&#xff0c;Kafka都不会立即就把这条消息发送出…...

2023 年山东省职业院校技能大赛(高等职业教育) “信息安全管理与评估”样题

2023 年山东省职业院校技能大赛&#xff08;高等职业教育&#xff09; “信息安全管理与评估”样题 目录 任务 1 网络平台搭建&#xff08;50 分&#xff09; 任务 2 网络安全设备配置与防护&#xff08;250 分&#xff09; 模块二 网络安全事件响应、数字取证调查、应用程序安…...

Apache Web 服务器监控工具

将Apache Web 服务器监控纳入 IT 基础架构管理策略有助于先发制人地识别性能瓶颈&#xff0c;这种主动监控方法提供必要的数据&#xff0c;以确保 Web 服务器能够胜任任务&#xff0c;并在需要时进行优化。保证客户获得流畅、无忧的用户体验可以大大有助于巩固他们对组织的信任…...

MySQL执行语句 Table ‘mysql.servers‘ doesn‘t exist

执行语句报错&#xff1a; mysql> flush privileges; ERROR 1146 (42S02): Table mysql.servers doesnt exist解决&#xff1a; 进入数据库 删除servers表 mysql> use mysql Database changed mysql> drop table if exists servers; Query OK, 0 rows affected, …...

在datagridview列显示下拉操作

DataGridViewComboBoxExColumn 设定好类型 需要设置的地方是&#xff1a; 绑定数据的操作&#xff1a; 因为此处绑定数据实际为数据 参数 显示的操作&#xff0c;不影响datasource的数据绑定 下一步 数据绑定&#xff1a; DGVCOrderZhuangtai.ValueType typeof(EOrderZhuan…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...