从增删改查到加密保护详解Java编辑PDF的完整指南

 更新时间:2026年07月11日 08:41:45   作者:用户372157426135  
在日常开发中,PDF 文档的生成与编辑是绕不开的需求——无论是生成报表、添加水印,还是替换图片、加密分发,都需要一套稳定易用的工具。最近我在项目中梳理了一套完整的 PDF 操作方案,涵盖了添加、替换、

在日常开发中,PDF 文档的生成与编辑是绕不开的需求——无论是生成报表、添加水印,还是替换图片、加密分发,都需要一套稳定易用的工具。最近我在项目中梳理了一套完整的 PDF 操作方案,涵盖了添加、替换、删除和保护等常见场景,这里记录成文,供有需要的朋友参考。

一、环境配置

在开始之前,需要将 PDF 处理库引入项目。我采用的是 Spire.PDF for Java,它提供了丰富的 API,支持绝大多数 PDF 操作。如果你使用 Maven,可以在 ​​pom.xml​​ 中添加以下仓库和依赖:

<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.pdf</artifactId>
        <version>11.9.6</version>
    </dependency>
</dependencies>

如果你不使用 Maven,也可以直接从官网下载 JAR 包,并将其添加到项目的类路径中。完成引入后,即可开始编写代码。

二、加载文档

所有操作的第一步都是将 PDF 文件加载到内存中,得到一个 ​​PdfDocument​​ 对象:

PdfDocument doc = new PdfDocument();
doc.loadFromFile("C:\work\sample.pdf");

​loadFromFile​​ 方法接收文件路径作为参数,支持绝对路径和相对路径。加载成功后,后续的增删改查都将围绕该文档对象进行。

三、内容添加

3.1 添加页面

若需在文档末尾追加一个新页面,可以使用 ​​getPages().add()​​ 方法:

PdfPageBase newPage = doc.getPages().add(PdfPageSize.A4, new PdfMargins(54));
newPage.getCanvas().drawString("这是新添加的页面内容", 
    new PdfTrueTypeFont(new Font("微软雅黑", Font.PLAIN, 18)), 
    PdfBrushes.getBlue(), 0, 0);

上述代码创建了一个 A4 大小的页面,左右边距为 54 点,并在页面左上角绘制了一行蓝色文字。​​drawString​​ 方法支持指定字体、颜色和坐标位置。

3.2 添加文字

如果需要在已有页面的指定矩形区域内插入文字(自动换行),可以这样实现:

PdfPageBase page = doc.getPages().get(0);
Rectangle2D.Float rect = new Rectangle2D.Float(54, 300, 400, 100);
PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("宋体", Font.PLAIN, 14));
PdfSolidBrush brush = new PdfSolidBrush(new PdfRGBColor(Color.BLACK));
page.getCanvas().drawString("这段文字将被绘制在指定的矩形区域内,超出部分会自动换行。", font, brush, rect);

通过 ​​Rectangle2D.Float​​ 定义区域的位置和大小,文字会自适应换行,非常适合填充表格或注释。

3.3 插入图片

往 PDF 中插入图片(如 Logo、签名)同样简单:

PdfImage image = PdfImage.fromFile("C:\work\logo.png");
page.getCanvas().drawImage(image, 100, 500);

​fromFile​​ 加载图片文件,​​drawImage​​ 将其绘制在指定坐标(左上角)。如需缩放,可以传入宽度和高度参数的重载方法。

3.4 添加表格

表格是数据展示的常用元素,Spire.PDF 支持从二维数组直接生成表格:

PdfTable table = new PdfTable();
String[][] data = {
    {"姓名", "部门", "入职年份"},
    {"张明", "研发", "2019"},
    {"李丽", "市场", "2020"},
    {"王强", "财务", "2018"}
};
table.setDataSource(data);
// 自定义表格样式
PdfTableStyle style = new PdfTableStyle();
style.getDefaultStyle().setFont(new PdfTrueTypeFont(new Font("Arial", Font.PLAIN, 12)));
table.setStyle(style);
// 在页面上绘制表格
table.draw(page, new Point2D.Float(50, 200));

​setDataSource​​ 接受数据源,​​draw​​ 方法指定表格左上角的起始坐标。样式支持字体、边框、背景色等自定义。

3.5 添加注释

弹出式注释可以增加文档的交互性,例如添加批注或提醒:

PdfPopupAnnotation popup = new PdfPopupAnnotation();
popup.setLocation(new Point2D.Double(200, 400));
popup.setText("请确认此数据是否准确。");
popup.setIcon(PdfPopupIcon.Comment);
popup.setColor(new PdfRGBColor(Color.YELLOW));
page.getAnnotations().add(popup);

​setLocation​​ 设定注释图标的位置,​​setText​​ 填入提示内容,最后添加到页面的注释集合中。

四、内容替换

4.1 替换文字

当需要批量修改文档中的特定词汇时,可以使用文本替换功能。例如将全文的“Water”替换为“H₂O”:

PdfTextReplaceOptions options = new PdfTextReplaceOptions();
options.setReplaceType(EnumSet.of(ReplaceActionType.IgnoreCase)); // 忽略大小写

for (int i = 0; i < doc.getPages().getCount(); i++) {
    PdfPageBase page = doc.getPages().get(i);
    PdfTextReplacer replacer = new PdfTextReplacer(page);
    replacer.setOptions(options);
    replacer.replaceAllText("Water", "H₂O");
}

​PdfTextReplacer​​ 针对每一页执行替换,​​ReplaceActionType.IgnoreCase​​ 表示不区分大小写。注意该方法仅适用于文本内容,对图片或扫描件无效。

4.2 替换图片

如果文档中的某张图片需要更新(如更换 Logo),可按以下步骤操作:

PdfImageHelper helper = new PdfImageHelper();
PdfImageInfo[] imageInfos = helper.getImagesInfo(page); // 获取页面上所有图片信息
PdfImage newImage = PdfImage.fromFile("C:\work\new_logo.png");
helper.replaceImage(imageInfos[0], newImage); // 替换第一张图片

​getImagesInfo​​ 返回图片信息数组,​​replaceImage​​ 根据索引或具体信息替换。如需替换指定位置的图片,可遍历 ​​imageInfos​​ 对比坐标后再操作。

五、内容删除

5.1 删除页面

doc.getPages().removeAt(0); // 删除第一页

​removeAt​​ 方法接收页码索引(从 0 开始),执行后该页即被移除。

5.2 删除图片

helper.deleteImage(imageInfos[0]); // 删除第一张图片

与替换类似,通过 ​​PdfImageHelper​​ 获取图片信息后调用 ​​deleteImage​​。

5.3 删除注释

page.getAnnotationsWidget().removeAt(0); // 删除第一个注释

​getAnnotationsWidget​​ 返回注释集合,​​removeAt​​ 按索引移除。

5.4 删除附件

如果文档包含附件(如嵌入的 PDF 或 Excel 文件),可以这样清理:

PdfAttachmentCollection attachments = doc.getAttachments();
if (attachments.size() > 0) {
    attachments.removeAt(0);
}

先获取附件集合,判断非空后删除指定索引的附件。

六、安全保护

6.1 添加水印

为了保护版权或标识文档状态,常需添加文本水印。以下代码在每一页的中心位置绘制半透明的“机密”字样:

PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("黑体", Font.PLAIN, 50), true);
String watermark = "机密";
float opacity = 0.3f;

for (int i = 0; i < doc.getPages().getCount(); i++) {
    PdfPageBase page = doc.getPages().get(i);
    page.getCanvas().setTransparency(opacity);
    Dimension2D textSize = font.measureString(watermark);
    double x = (page.getActualSize().getWidth() - textSize.getWidth()) / 2;
    double y = (page.getActualSize().getHeight() - textSize.getHeight()) / 2;
    page.getCanvas().drawString(watermark, font, PdfBrushes.getGray(), x, y);
}

通过 ​​setTransparency​​ 控制透明度,​​measureString​​ 计算文字宽度以实现水平垂直居中。

6.2 加密保护

对敏感文档进行密码加密,可防止未授权访问。下面的代码使用 AES-256 算法加密,并限制编辑和复制权限:

String userPassword = "user123";
String ownerPassword = "admin456";

PdfPasswordSecurityPolicy policy = new PdfPasswordSecurityPolicy(userPassword, ownerPassword);
policy.setEncryptionAlgorithm(PdfEncryptionAlgorithm.AES_256);
policy.setDocumentPrivilege(PdfDocumentPrivilege.getAllowAll());
policy.getDocumentPrivilege().setAllowModifyContents(false);
policy.getDocumentPrivilege().setAllowContentCopying(false);

doc.encrypt(policy);

​userPassword​​ 用于打开文档,​​ownerPassword​​ 用于管理权限。通过 ​​setDocumentPrivilege​​ 可精细控制是否允许打印、修改、复制等操作。

七、保存与释放

所有操作完成后,将修改后的文档保存到新路径,并关闭资源:

doc.saveToFile("C:\work\output.pdf");
doc.close();

建议使用新文件名保存,避免覆盖原始文件。

结语

以上便是我在项目中常用的 PDF 操作方法,涵盖了添加、替换、删除、水印和加密等核心需求。这套方案借助成熟的第三方库,大大简化了 PDF 的编程处理,代码简洁且易于扩展。如果你也有类似的 PDF 处理任务,不妨参考上述示例,相信能够快速落地。实际使用时,根据具体需求调整参数即可。

到此这篇关于从增删改查到加密保护详解Java编辑PDF的完整指南的文章就介绍到这了,更多相关Java编辑PDF内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot如何在运行时动态添加数据源

    SpringBoot如何在运行时动态添加数据源

    这篇文章主要介绍了SpringBoot如何在运行时动态添加数据源,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • 50 道Java 线程面试题(经典)

    50 道Java 线程面试题(经典)

    java 线程面试题是比较热门的面试题,下面小编给大家分享了50道java线程面试题必掌握,大家来一起学习吧为面试好好准备吧
    2016-11-11
  • MyBatis的模糊查询mapper.xml的写法讲解

    MyBatis的模糊查询mapper.xml的写法讲解

    这篇文章主要介绍了MyBatis的模糊查询mapper.xml的写法讲解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • SpringBoot如何实现固定版本

    SpringBoot如何实现固定版本

    SpringBoot项目中固定依赖版本可避免兼容性问题,常用方法包括使用spring-boot-starter-parent统一管理、dependencyManagement手动指定版本及BOM,推荐前两者以简化管理并确保一致性
    2025-09-09
  • SpringBoot学习之Json数据交互的方法

    SpringBoot学习之Json数据交互的方法

    这篇文章主要介绍了SpringBoot学习之Json数据交互的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • Kosaraju算法详解

    Kosaraju算法详解

    这篇文章主要为大家详细介绍了Kosaraju算法,Kosaraju算法可以计算出一个有向图的强连通分量,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • Java实现差分数组的示例详解

    Java实现差分数组的示例详解

    差分数组是由原数组进化而来,值为原数组当前位置值减去上一个位置的值。本文将通过例题详解如何利用Java实现差分数组,需要的可以参考一下
    2022-06-06
  • java使用hadoop实现关联商品统计

    java使用hadoop实现关联商品统计

    本篇文章java使用hadoop实现关联商品统计,可以实现商品的关联统计,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2016-10-10
  • Java中使用阻塞队列控制线程集实例

    Java中使用阻塞队列控制线程集实例

    这篇文章主要介绍了Java控制阻塞队列线程集实例,本文用一个程序展示了如何使用阻塞队列来控制线程集,程序功能是在一个目录及它的所有子目录下搜索所有文件,打印出包含指定关键字的文件列表,需要的朋友可以参考下
    2015-01-01
  • java 单例模式和工厂模式实例详解

    java 单例模式和工厂模式实例详解

    这篇文章主要介绍了Java设计模式编程中的单例模式和简单工厂模式以及实例,使用设计模式编写代码有利于团队协作时程序的维护,需要的朋友可以参考下
    2017-04-04

最新评论