如何使用PDFBox移除PDF中的贝茨编号?
如何使用PDFBox移除PDF中的贝茨编号?
我之前也碰到过一模一样的问题!普通页眉页脚用覆盖法就能搞定,但贝茨编号总是顽固地留在那里,后来才搞明白——它们往往不是普通的页面绘制内容,而是以注释(Annotation)或者表单域的形式存在的,这时候单纯用图片覆盖肯定不管用,因为这些元素的层级在页面内容流之上。
给你几个针对性的解决方案,按优先级试试:
1. 先检查并删除注释类型的贝茨编号
绝大多数工具添加的贝茨编号都是「Stamp(图章)注释」,它们独立于页面内容流,层级更高。你可以遍历页面的注释列表,定位到右下角的贝茨注释并删除:
PDDocument document = PDDocument.load(file); for (PDPage page : document.getPages()) { // 先把注释列表转成新集合,避免遍历的时候修改原集合报错 List<PDAnnotation> annotations = new ArrayList<>(page.getAnnotations()); float pageWidth = page.getMediaBox().getWidth(); for (PDAnnotation annotation : annotations) { // 判断是不是图章注释 if (annotation instanceof PDAnnotationStamp) { PDAnnotationStamp stamp = (PDAnnotationStamp) annotation; PDRectangle stampRect = stamp.getRectangle(); // 检查是否在右下角区域(可根据实际情况调整数值) boolean isBottomRightStamp = stampRect.getLowerLeftX() > pageWidth - 100 && stampRect.getLowerLeftY() < 50; if (isBottomRightStamp) { page.removeAnnotation(annotation); } } } } // 别忘了保存文档 document.save("处理后的文件.pdf"); document.close();
2. 如果是表单域类型的贝茨编号
有些工具会把贝茨编号做成可编辑的表单文本域,这时候需要从AcroForm里移除对应的域:
PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm(); if (acroForm != null) { List<PDField> fields = new ArrayList<>(acroForm.getFields()); for (PDField field : fields) { // 获取域对应的页面和位置 PDAnnotationWidget widget = field.getWidgets().get(0); PDPage fieldPage = widget.getPage(); float pageWidth = fieldPage.getMediaBox().getWidth(); PDRectangle fieldRect = widget.getRectangle(); // 判断是否在右下角区域 boolean isBottomRightField = fieldRect.getLowerLeftX() > pageWidth - 100 && fieldRect.getLowerLeftY() < 50; if (isBottomRightField) { acroForm.getFields().remove(field); } } }
3. 极端情况:贝茨编号是页面内容流的一部分
如果贝茨是直接绘制在页面内容里的(这种情况比较少见),那覆盖法不管用可能是因为你用了APPEND模式,导致覆盖的图片在贝茨下面。这时候可以尝试解析内容流删除对应的文本操作(需要了解PDF内容流语法,相对复杂),或者用PDPageContentStream.AppendMode.OVERWRITE模式重新构建页面内容(注意保留原页面的其他必要内容)。不过这种情况概率很低,先试试前两种方法基本能解决。
另外,你之前代码里的坐标是对的,但因为贝茨是注释,所以覆盖的图片在它下面,看不到效果。先删注释再看,如果还有残留再检查是不是表单域。
备注:内容来源于stack exchange,提问作者Morkus
相关产品推荐
相关产品推荐

