如何使用Apache PDFBox锁定PDF指定表单域使其不可编辑
使用Apache PDFBox填充PDF并锁定指定字段
核心实现步骤
- 加载服务器上的PDF模板文件
- 获取表单对象
PDAcroForm - 填充目标字段内容
- 将需要锁定的字段设置为只读状态
- 配置表单权限,保证未锁定字段仍可编辑
- 输出处理后的PDF文件
代码示例(Spring Rest接口)
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.interactive.form.*; import org.springframework.http.*; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @RestController public class PdfFillController { @PostMapping("/fill-pdf") public ResponseEntity<byte[]> fillAndLockPdf() throws IOException { // 加载服务器上的PDF模板 String templatePath = "/your/server/path/template.pdf"; try (PDDocument document = PDDocument.load(new File(templatePath))) { PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm(); if (acroForm == null) { throw new IllegalArgumentException("模板PDF不包含AcroForm表单"); } // 填充各类字段内容 // 文本框 PDTextField userNameField = (PDTextField) acroForm.getField("userName"); userNameField.setValue("张三"); // 复选框(假设导出值为"Yes") PDCheckbox agreeCheckbox = (PDCheckbox) acroForm.getField("agreeTerms"); agreeCheckbox.check(); // 下拉框 PDComboBox deptCombo = (PDComboBox) acroForm.getField("department"); deptCombo.setValue("技术部"); // 锁定指定字段 String[] lockedFieldNames = {"userName", "agreeTerms"}; for (String fieldName : lockedFieldNames) { PDField field = acroForm.getField(fieldName); if (field != null) { field.setReadOnly(true); // 兼容部分阅读器,额外设置字段只读标志 field.setFieldFlags(field.getFieldFlags() | PDField.READ_ONLY); } } // 配置表单,确保未锁定字段可正常编辑 acroForm.setNeedAppearances(true); acroForm.setSignaturesExist(false); acroForm.setAppendOnly(false); // 生成输出字节流 ByteArrayOutputStream baos = new ByteArrayOutputStream(); document.save(baos); // 构建响应返回给用户 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_PDF); headers.setContentDispositionFormData("attachment", "filled-form.pdf"); return new ResponseEntity<>(baos.toByteArray(), headers, HttpStatus.OK); } } }
关键说明
setReadOnly(true):PDFBox提供的便捷方法,直接标记字段为只读- 字段标志
PDField.READ_ONLY:补充设置字段标志,提升在不同PDF阅读器中的兼容性 setNeedAppearances(true):强制阅读器重新生成表单外观,避免填充后字段显示异常- 未加入
lockedFieldNames数组的字段,会保持可编辑状态,用户下载后可修改
内容的提问来源于stack exchange,提问作者Jonas Gredig
相关产品推荐
相关产品推荐

