iText生成PDF仅最后两页显示页码的问题求助
问题原因
你当前的代码存在两个核心问题:
- 事件处理器注册时机过晚:END_PAGE事件仅在页面创建完成时触发,你是在添加完页眉、客户列表等核心内容后才注册处理器,此时前3页已经生成,不会被处理器捕获,只有注册后新增的页面(比如日期段落生成的第4、5页)才会触发事件显示页码。
- 提前获取总页数不准确:在未添加完所有文档内容时调用
getNumberOfPages(),得到的总页数可能不是最终值,后续新增页面会导致页码显示错误。
解决方案
推荐采用写完所有内容后遍历页面添加页码的方式,逻辑直观且不易出错:
修改后主代码
// 假设已完成PdfDocument和Document的初始化 // ... // 添加所有文档内容 document.add(headerTable) document.add(font18) document.add(listaClientes) document.add( Paragraph( "\nListado enviado el: ${ LocalDate.now().toString() .let { reformatDate(it).replaceFirstChar(Char::titlecase) } } " ).setTextAlignment(TextAlignment.CENTER) ) // 所有内容添加完成后,获取最终总页数 val totalPages = pdfDocument.numberOfPages // 遍历每一页添加页码 for (pageNum in 1..totalPages) { val page = pdfDocument.getPage(pageNum) val pageSize = page.pageSize val x = pageSize.width - 50 val y = 20f // 可根据需求调整页码垂直位置 val canvas = Canvas(page, pageSize) val paragraph = Paragraph("Página $pageNum de $totalPages") .setTextAlignment(TextAlignment.RIGHT) canvas.showTextAligned( paragraph, x, y, TextAlignment.RIGHT, VerticalAlignment.BOTTOM, 0f ) canvas.close() } // 关闭文档 document.close()
替代方案:提前注册事件处理器
如果偏好使用事件驱动方式,需提前注册处理器,并在文档完成后补全总页数:
主代码
// 初始化文档后立即注册事件处理器 val handler = PageNumberHandler(pdfDocument) pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, handler) // 添加所有文档内容 document.add(headerTable) document.add(font18) document.add(listaClientes) document.add( Paragraph( "\nListado enviado el: ${ LocalDate.now().toString() .let { reformatDate(it).replaceFirstChar(Char::titlecase) } } " ).setTextAlignment(TextAlignment.CENTER) ) // 补全所有页码的总页数 handler.addTotalPages() document.close()
PageNumberHandler代码
class PageNumberHandler(val pdfDocument: PdfDocument) : IEventHandler { private val pageMap = mutableMapOf<PdfPage, Int>() override fun handleEvent(event: Event) { val docEvent = event as PdfDocumentEvent val page = docEvent.page // 记录每个页面的页码 pageMap[page] = pdfDocument.getPageNumber(page) } fun addTotalPages() { val totalPages = pdfDocument.numberOfPages pageMap.forEach { (page, pageNum) -> val pageSize = page.pageSize val x = pageSize.width - 50 val y = 20f val canvas = Canvas(page, pageSize) val paragraph = Paragraph("Página $pageNum de $totalPages") .setTextAlignment(TextAlignment.RIGHT) canvas.showTextAligned( paragraph, x, y, TextAlignment.RIGHT, VerticalAlignment.BOTTOM, 0f ) canvas.close() } } }
内容的提问来源于stack exchange,提问作者Rafel C.F
相关产品推荐
相关产品推荐

