如何在iText 7中获取当前页码?(替代iText 5中PdfWriter的getCurrentPageNumber()方法)
在iText 7中获取当前页码并处理分页逻辑(替代iText 5的
getCurrentPageNumber()) 我刚帮朋友解决过类似的iText 5到7的迁移问题,针对你需要获取当前页码并处理分页逻辑的需求,这里有两种实用的解决方案,适配你全程复用同一个Document实例的场景:
方法1:通过添加内容前后对比页码判断分页
这种方法简单直接,适合需要事后判断是否发生分页的场景(比如内容添加后才知道是否分页,然后追加标题)。
核心思路是:利用PdfDocument.getNumberOfPages()获取已完成的页面数,在添加可能分页的内容前后分别记录页码,对比后判断是否发生了分页。
代码示例
// 修改你的buildBody方法 public void buildBody(PdfData pdfData, Document document) { PdfDocument pdfDocument = document.getPdfDocument(); // 记录添加内容前的页码 int pageBefore = pdfDocument.getNumberOfPages(); // 添加可能触发分页的内容 Paragraph longContent = new Paragraph(pdfData.getLongBillContent()) .setFontSize(12) .setMarginBottom(10); document.add(longContent); // 对比页码,判断是否分页 int pageAfter = pdfDocument.getNumberOfPages(); if (pageAfter > pageBefore) { // 分页触发,添加额外标题 Paragraph sectionHeader = new Paragraph("后续账单明细") .setBold() .setFontSize(14) .setMarginTop(15); document.add(sectionHeader); } // 继续添加其他内容... }
注意事项
- 当内容刚好填满当前页时,iText 7会自动创建新页面,因此
pageAfter会比pageBefore大1,这个判断逻辑是可靠的。 - 不需要额外维护状态,代码侵入性低。
方法2:利用页面事件跟踪当前页码(提前预判分页)
如果你需要提前判断内容是否会超出当前页面(比如在添加内容前就决定是否要插入分页和标题),可以结合你已经在使用的页面事件处理器,维护一个全局的页码跟踪器。
步骤1:创建页码跟踪器类
// 简单的状态跟踪类,确保全程复用同一实例 public class PageNumberTracker { private int currentPage = 0; public int getCurrentPage() { return currentPage; } public void updateCurrentPage(int newPageNum) { this.currentPage = newPageNum; } }
步骤2:修改页面事件处理器更新页码
在START_PAGE事件触发时,iText已经完成了新页面的创建,此时可以获取到当前正确的页码:
public class StartPageHandler<T> implements IEventHandler { private final PdfData pdfData; private final Document document; private final PageNumberTracker pageTracker; // 修改构造函数,传入页码跟踪器 public StartPageHandler(PdfData pdfData, Document document, PageNumberTracker pageTracker) { this.pdfData = pdfData; this.document = document; this.pageTracker = pageTracker; } @Override public void handleEvent(Event event) { PdfDocumentEvent docEvent = (PdfDocumentEvent) event; PdfDocument pdfDoc = docEvent.getDocument(); // 更新当前页码(START_PAGE触发时,新页面已经创建,getNumberOfPages()就是当前页号) pageTracker.updateCurrentPage(pdfDoc.getNumberOfPages()); // 你的原有页眉逻辑 Rectangle rectangle = new Rectangle(51, 750, 500, 60); document.setRenderer(new ColumnDocumentRenderer(document, new Rectangle[]{rectangle})); document.add(new LineSeparator()); document.add(new Paragraph(pdfData.getBillHeaderInfo())); } }
步骤3:在buildBody中预判分页
通过当前页面的剩余空间和内容高度对比,判断是否会分页:
public void buildBody(PdfData pdfData, Document document, PageNumberTracker pageTracker) { int currentPage = pageTracker.getCurrentPage(); if (currentPage == 0) { // 处理初始状态(还没触发START_PAGE的情况) currentPage = 1; } // 获取当前页面的剩余空间 PdfPage page = document.getPdfDocument().getPage(currentPage); Rectangle pageSize = page.getPageSizeWithRotation(); float usedBottom = document.getRenderer().getCurrentArea().getBBox().getBottom(); float remainingHeight = pageSize.getHeight() - document.getBottomMargin() - usedBottom; // 计算待添加内容的高度 Paragraph longContent = new Paragraph(pdfData.getLongBillContent()); float contentHeight = longContent.createRendererSubTree() .setParent(document.getRenderer()) .calculateMaxHeight(); // 判断内容是否会超出当前页 if (contentHeight > remainingHeight) { // 先插入分页,再添加标题 document.add(new AreaBreak()); Paragraph sectionHeader = new Paragraph("新账单段标题") .setBold() .setFontSize(14) .setMarginTop(10); document.add(sectionHeader); } // 添加内容 document.add(longContent); }
注意事项
- 这个方法可以提前预判分页,适合需要在内容前插入标题的场景。
- 要确保
PageNumberTracker在整个PDF生成过程中是同一个实例,避免状态混乱。
初始化时的整合示例
public void generateMonthlyBill(String filename, PdfData pdfData) throws IOException { PdfWriter writer = new PdfWriter(new FileOutputStream(filename)); PdfDocument pdfDocument = new PdfDocument(writer); Document document = new Document(pdfDocument, PageSize.A4); document.setMargins(235, 35, 0, 38); // 创建页码跟踪器 PageNumberTracker pageTracker = new PageNumberTracker(); // 注册事件处理器,传入跟踪器 pdfDocument.addEventHandler(PdfDocumentEvent.START_PAGE, new StartPageHandler<>(pdfData, document, pageTracker)); pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, new EndPageHandler<>(pdfData, document, pageTracker)); // 调用buildBody buildBody(pdfData, document, pageTracker); document.close(); }
内容的提问来源于stack exchange,提问作者skorpyo
相关产品推荐
相关产品推荐

