如何用Java从PDF提取指定区域页脚并添加至另一PDF所有页面
Java实现PDF页脚提取与批量添加
依赖选择
推荐使用Apache PDFBox(轻量、API直观)或iText 7(功能丰富),以下分别给出两种库的实现示例。先添加Maven依赖:
Apache PDFBox 依赖
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.32</version> </dependency> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox-tools</artifactId> <version>2.0.32</version> </dependency>
iText 7 依赖
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itext7-core</artifactId> <version>7.2.5</version> </dependency>
步骤1:从单页PDF提取指定区域的页脚(转为图片)
已知提取区域的精确坐标(Selenium返回的是左上角原点坐标,需转换为PDF的左下角原点坐标):
- Selenium坐标:
xSel(左距)、ySel(上距)、width(宽度)、height(高度) - PDF页面高度:
pageHeight(可从PDF文档获取) - 转换后PDF坐标:
xPdf = xSel,yPdf = pageHeight - ySel - height
Apache PDFBox 实现提取
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.rendering.PDFRenderer; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; public class FooterExtractor { public static BufferedImage extractFooterAsImage(String sourcePdfPath, float xSel, float ySel, float width, float height) throws Exception { try (PDDocument document = PDDocument.load(new File(sourcePdfPath))) { PDPage page = document.getPage(0); // 获取PDF页面高度(单位:点,1点=1/72英寸) float pageHeight = page.getMediaBox().getHeight(); // 转换坐标为PDF左下角原点 float xPdf = xSel; float yPdf = pageHeight - ySel - height; // 渲染整页为高清晰度图片 PDFRenderer renderer = new PDFRenderer(document); BufferedImage fullPageImage = renderer.renderImageWithDPI(0, 300); // 把PDF点坐标转为像素坐标(DPI=300) int dpi = 300; int xPixel = (int) (xPdf * dpi / 72); int yPixel = (int) (yPdf * dpi / 72); int widthPixel = (int) (width * dpi / 72); int heightPixel = (int) (height * dpi / 72); return fullPageImage.getSubimage(xPixel, yPixel, widthPixel, heightPixel); } } // 测试:提取后保存为本地图片 public static void main(String[] args) throws Exception { BufferedImage footerImage = extractFooterAsImage("source.pdf", 50, 800, 500, 30); ImageIO.write(footerImage, "PNG", new File("footer.png")); } }
步骤2:将页脚添加到目标PDF的每一页
Apache PDFBox 实现批量添加
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; import java.io.File; public class FooterAdder { public static void addFooterToAllPages(String targetPdfPath, BufferedImage footerImage, float xSel, float ySel, float width, float height) throws Exception { try (PDDocument targetDoc = PDDocument.load(new File(targetPdfPath))) { // 将BufferedImage转为PDF可识别的图片对象 PDImageXObject footerXObject = PDImageXObject.createFromByteArray(targetDoc, ImageIO.writeToBytes(footerImage, "PNG"), "footer"); for (PDPage page : targetDoc.getPages()) { float pageHeight = page.getMediaBox().getHeight(); // 转换坐标为PDF左下角原点 float xPdf = xSel; float yPdf = pageHeight - ySel - height; // 打开内容流,在原有内容下方追加页脚 try (PDPageContentStream contentStream = new PDPageContentStream(targetDoc, page, PDPageContentStream.AppendMode.APPEND, true)) { // 按指定坐标和尺寸绘制页脚图片 contentStream.drawImage(footerXObject, xPdf, yPdf, width, height); } } // 保存修改后的PDF targetDoc.save("target_with_footer.pdf"); } } // 测试:完整流程调用 public static void main(String[] args) throws Exception { BufferedImage footer = FooterExtractor.extractFooterAsImage("source.pdf", 50, 800, 500, 30); addFooterToAllPages("target.pdf", footer, 50, 800, 500, 30); } }
关键注意事项
- 坐标转换:Selenium以左上角为原点,PDF以左下角为原点,必须根据页面高度转换y坐标,否则页脚位置会偏移。
- DPI一致性:提取图片时的DPI要和坐标转换逻辑匹配,避免页脚模糊或尺寸偏差。
- 内容层级:使用
APPEND模式会把页脚放在原有内容下方,若需显示在内容上方,可改用PREPEND模式。
内容的提问来源于stack exchange,提问作者blank04
相关产品推荐
相关产品推荐

