Java 编辑 PDF:从增删改查到加密保护 在日常开发中PDF 文档的生成与编辑是绕不开的需求——无论是生成报表、添加水印还是替换图片、加密分发都需要一套稳定易用的工具。最近我在项目中梳理了一套完整的 PDF 操作方案涵盖了添加、替换、删除和保护等常见场景这里记录成文供有需要的朋友参考。一、环境配置在开始之前需要将 PDF 处理库引入项目。我采用的是Spire.PDF for Java它提供了丰富的 API支持绝大多数 PDF 操作。如果你使用 Maven可以在pom.xml中添加以下仓库和依赖repositoriesrepositoryidcom.e-iceblue/idnamee-iceblue/nameurlhttps://repo.e-iceblue.com/nexus/content/groups/public//url/repository/repositoriesdependenciesdependencygroupIde-iceblue/groupIdartifactIdspire.pdf/artifactIdversion11.9.6/version/dependency/dependencies如果你不使用 Maven也可以直接从官网下载 JAR 包并将其添加到项目的类路径中。完成引入后即可开始编写代码。二、加载文档所有操作的第一步都是将 PDF 文件加载到内存中得到一个PdfDocument对象PdfDocumentdocnewPdfDocument();doc.loadFromFile(C:\\work\\sample.pdf);loadFromFile方法接收文件路径作为参数支持绝对路径和相对路径。加载成功后后续的增删改查都将围绕该文档对象进行。三、内容添加3.1 添加页面若需在文档末尾追加一个新页面可以使用getPages().add()方法PdfPageBasenewPagedoc.getPages().add(PdfPageSize.A4,newPdfMargins(54));newPage.getCanvas().drawString(这是新添加的页面内容,newPdfTrueTypeFont(newFont(微软雅黑,Font.PLAIN,18)),PdfBrushes.getBlue(),0,0);上述代码创建了一个 A4 大小的页面左右边距为 54 点并在页面左上角绘制了一行蓝色文字。drawString方法支持指定字体、颜色和坐标位置。3.2 添加文字如果需要在已有页面的指定矩形区域内插入文字自动换行可以这样实现PdfPageBasepagedoc.getPages().get(0);Rectangle2D.FloatrectnewRectangle2D.Float(54,300,400,100);PdfTrueTypeFontfontnewPdfTrueTypeFont(newFont(宋体,Font.PLAIN,14));PdfSolidBrushbrushnewPdfSolidBrush(newPdfRGBColor(Color.BLACK));page.getCanvas().drawString(这段文字将被绘制在指定的矩形区域内超出部分会自动换行。,font,brush,rect);通过Rectangle2D.Float定义区域的位置和大小文字会自适应换行非常适合填充表格或注释。3.3 插入图片往 PDF 中插入图片如 Logo、签名同样简单PdfImageimagePdfImage.fromFile(C:\\work\\logo.png);page.getCanvas().drawImage(image,100,500);fromFile加载图片文件drawImage将其绘制在指定坐标左上角。如需缩放可以传入宽度和高度参数的重载方法。3.4 添加表格表格是数据展示的常用元素Spire.PDF 支持从二维数组直接生成表格PdfTabletablenewPdfTable();String[][]data{{姓名,部门,入职年份},{张明,研发,2019},{李丽,市场,2020},{王强,财务,2018}};table.setDataSource(data);// 自定义表格样式PdfTableStylestylenewPdfTableStyle();style.getDefaultStyle().setFont(newPdfTrueTypeFont(newFont(Arial,Font.PLAIN,12)));table.setStyle(style);// 在页面上绘制表格table.draw(page,newPoint2D.Float(50,200));setDataSource接受数据源draw方法指定表格左上角的起始坐标。样式支持字体、边框、背景色等自定义。3.5 添加注释弹出式注释可以增加文档的交互性例如添加批注或提醒PdfPopupAnnotationpopupnewPdfPopupAnnotation();popup.setLocation(newPoint2D.Double(200,400));popup.setText(请确认此数据是否准确。);popup.setIcon(PdfPopupIcon.Comment);popup.setColor(newPdfRGBColor(Color.YELLOW));page.getAnnotations().add(popup);setLocation设定注释图标的位置setText填入提示内容最后添加到页面的注释集合中。四、内容替换4.1 替换文字当需要批量修改文档中的特定词汇时可以使用文本替换功能。例如将全文的“Water”替换为“H₂O”PdfTextReplaceOptionsoptionsnewPdfTextReplaceOptions();options.setReplaceType(EnumSet.of(ReplaceActionType.IgnoreCase));// 忽略大小写for(inti0;idoc.getPages().getCount();i){PdfPageBasepagedoc.getPages().get(i);PdfTextReplacerreplacernewPdfTextReplacer(page);replacer.setOptions(options);replacer.replaceAllText(Water,H₂O);}PdfTextReplacer针对每一页执行替换ReplaceActionType.IgnoreCase表示不区分大小写。注意该方法仅适用于文本内容对图片或扫描件无效。4.2 替换图片如果文档中的某张图片需要更新如更换 Logo可按以下步骤操作PdfImageHelperhelpernewPdfImageHelper();PdfImageInfo[]imageInfoshelper.getImagesInfo(page);// 获取页面上所有图片信息PdfImagenewImagePdfImage.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 文件可以这样清理PdfAttachmentCollectionattachmentsdoc.getAttachments();if(attachments.size()0){attachments.removeAt(0);}先获取附件集合判断非空后删除指定索引的附件。六、安全保护6.1 添加水印为了保护版权或标识文档状态常需添加文本水印。以下代码在每一页的中心位置绘制半透明的“机密”字样PdfTrueTypeFontfontnewPdfTrueTypeFont(newFont(黑体,Font.PLAIN,50),true);Stringwatermark机密;floatopacity0.3f;for(inti0;idoc.getPages().getCount();i){PdfPageBasepagedoc.getPages().get(i);page.getCanvas().setTransparency(opacity);Dimension2DtextSizefont.measureString(watermark);doublex(page.getActualSize().getWidth()-textSize.getWidth())/2;doubley(page.getActualSize().getHeight()-textSize.getHeight())/2;page.getCanvas().drawString(watermark,font,PdfBrushes.getGray(),x,y);}通过setTransparency控制透明度measureString计算文字宽度以实现水平垂直居中。6.2 加密保护对敏感文档进行密码加密可防止未授权访问。下面的代码使用 AES-256 算法加密并限制编辑和复制权限StringuserPassworduser123;StringownerPasswordadmin456;PdfPasswordSecurityPolicypolicynewPdfPasswordSecurityPolicy(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 处理任务不妨参考上述示例相信能够快速落地。实际使用时根据具体需求调整参数即可希望对你有帮助。