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

news2024/11/22 19:58:03

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

前言

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

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

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

相关文章

数字人er-nerf安装

目录 服务器环境 环境准备 1.下载源码 2.安装Ancoda环境 3.安装cudatoolkit 4.安装cuDNN 5.安装pytorch 6.安装requirements 7.安装tensorflow 8.安装pytorch3d 9.gcc安装 训练准备 训练 最近安装er-nerf&#xff0c;安装了很久&#xff0c;各种报错&#xff0c;我…

go学习之反射知识

反射 文章目录 反射1、反射的使用场景1&#xff09;结构体标签的应用2&#xff09;使用反射机制编写函数的适配器&#xff08;桥连接&#xff09; 2、反射的基本介绍-1.基本介绍-2.反射的图解-3.反射重要的函数和概念 3.反射快速入门-1.请编写一个函数&#xff0c;演示对&#…

【Vue】router.push用法实现路由跳转

目录 router.push用法 在Login.vue中 在Register.vue中 ​ 上一篇&#xff1a;登录与注册界面的制作 https://blog.csdn.net/m0_67930426/article/details/134895214?spm1001.2014.3001.5502 制作了登录与注册界面&#xff0c;并介绍了相关表单元素即属性的用法 在登录页面…

OpenHarmony应用开发——创建第一个OpenHarmonry工程

一、前言 本文主要介绍DevEco Studio的相关配置&#xff0c;以及创建第一个OpenHarmony应用程序。 二、详细步骤 打开DevEco Studio. 进入Settings. 随后SDK选择OpenHarmony&#xff0c;并完成下述API的选择与下载. 等待下载完成后&#xff0c;创建第一个Project. 此处选择Emp…

区块链技术的未来,了解去中心化应用的新视角

小编介绍&#xff1a;10年专注商业模式设计及软件开发&#xff0c;擅长企业生态商业模式&#xff0c;商业零售会员增长裂变模式策划、商业闭环模式设计及方案落地&#xff1b;扶持10余个电商平台做到营收过千万&#xff0c;数百个平台达到百万会员&#xff0c;欢迎咨询。 随着…

C/C++,动态 DP 问题的计算方法与源程序

1 文本格式 #include <bits/stdc.h> using namespace std; typedef long long LL; const int maxn 500010; const int INF 0x3f3f3f3f; int Begin[maxn], Next[maxn], To[maxn], e, n, m; int size[maxn], son[maxn], top[maxn], fa[maxn], dis[maxn], p[maxn], i…

推荐开源项目-网络应用协议框架Socket.D

基于事件和语义消息流的网络应用协议 Socket.D 0 代码仓库地址1 该开源项目特点2 项目结构3 核心理念-协议帧Frame4 结束语 0 代码仓库地址 https://gitee.com/noear/socketd 1 该开源项目特点 代码风格优雅文档说明齐全测试用例非常人性化上手快&#xff0c;代码用例很多代…

基于双树复小波变换和稀疏表示的多光谱和彩色图像融合算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 双树复小波变换原理 4.2 稀疏表示原理 4.3 基于双树复小波变换和稀疏表示的图像融合算法 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序…

Appium 自动化自学篇 —— 初识Appium自动化!

Appium 简介 随着移动终端的普及&#xff0c;手机应用越来越多&#xff0c;也越来越重要。而作为测试 的我们也要与时俱进&#xff0c;努力学习手机 App 的相关测试&#xff0c;文章将介绍手机自动化测试框架 Appium 。 那究竟什么是 Appium 呢? 接下来我们一起来学习PythonS…

Spring 的设计思想、创建和使用、Bean 作用域和生命周期

文章目录 Spring 设计思想Spring 是什么&#xff1f;什么是 IoC&#xff1f; Spring 创建和使用创建 Spring 项目注册 Bean 对象获取并使用 Bean 对象 Spring 更方便地存储和读取对象配置文件使用注解使用类注解使用方法注解 获取 Bean 对象属性注入Setter 注入构造方法注入Res…

基于FPGA的视频接口之高速IO(光纤)

简介 对于高速IO口配置光纤,现在目前大部分开发板都有配置,且也有说明,在此根据自己的工作经验以及对于各开发板的说明归纳 通过高速IO接口,以及硬件配置,可以实现对于光纤的收发功能,由于GTX的速率在500Mbs到10Gbps之间,但通道高速io可配置光纤10G硬件,物理通完成,则…

Unity 修改游戏对象的旋转角度Rotation的方法

在Unity中要修改游戏对象中的旋转角度&#xff0c;即下图中的Rotation: 有三个方法&#xff1a; 1、 使用欧拉角&#xff08;Euler Angles&#xff09;&#xff1a;欧拉角是一组表示旋转的三个角度值&#xff08;绕X轴的旋转、绕Y轴的旋转和绕Z轴的旋转&#xff09;。 transf…

Unity光照模型实践

光照作为3D渲染中最重要的部分之一&#xff0c;如何去模拟真实环境的光照是重要的研究内容&#xff0c;但是现实环境光照过于复杂&#xff0c;有很多经典好用的光照模型去近似真实光照。 根据基础的Phong模型 最终某个点的结果为 环境光Ambient 漫反射光Diffuse 高光Specula…

Hadoop高可用(主备切换)---配合Zookeeper

1. Hadoop高可用(Hadoop High Availability)概述 HA(High Available), 高可用&#xff0c;是保证业务连续性的有效解决方案&#xff0c;一般有两个或两个以上的节点&#xff0c;分为活动节点&#xff08;Active&#xff09;及备用节点&#xff08;Standby&#xff09;。通常把…

Mendix 创客访谈录|合作伙伴谈Mendix对销售团队的业务价值

本期创客 段晓科 适途科技 咨询中心负责人 大家好&#xff0c;我叫段晓科&#xff0c;非软件开发专业&#xff0c;拥有多年制造行业数字化解决方案经验&#xff0c;擅长从0到1 的产品构建和产品落地服务。 目前任职于适途科技&#xff0c;自2021年3月至今负责Mendix低代码平台…

sonar扫描代码用法

1 mvn的setting配置文件中配置如下 其中sonar.host.url是本地或者服务器上自己安装的sonar <pluginGroups><pluginGroup>org.sonarsource.scanner.maven</pluginGroup></pluginGroups><profile><id>sonar</id><activation>&l…

boost graph之基础

结构 属性相关 #mermaid-svg-PZQvKfbwNSnyXO9g {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-PZQvKfbwNSnyXO9g .error-icon{fill:#552222;}#mermaid-svg-PZQvKfbwNSnyXO9g .error-text{fill:#552222;stroke:#5522…

文心一言 VS 讯飞星火 VS chatgpt (155)-- 算法导论12.3 2题

二、用go语言&#xff0c;假设通过反复向一棵树中插人互不相同的关键字来构造一棵二叉搜索树。证明&#xff1a;在这棵树中查找关键字所检查过的结点数目等于先前插入这个关键字所检查的结点数目加 1。 文心一言&#xff1a; 为了证明这个结论&#xff0c;我们可以使用二叉搜…

【代码随想录】刷题笔记Day34

前言 考过概率论&#xff0c;发过一场烧&#xff0c;兜兜转转又一月&#xff0c;轻舟已撞万重山&#xff0c;赶紧刷题 贪心算法理论基础 贪心的本质&#xff1a;局部最优→全局最优无套路&#xff0c;常识性推导 举反例 455. 分发饼干 - 力扣&#xff08;LeetCode&#xf…

Python (六) 绘图

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…