iTextPDF实现按产品分组展示并在组末显示总金额问题
解决iTextPDF分组后添加组总计行的问题
我正好碰到过类似的需求,给你梳理个靠谱的实现思路和代码!你的核心问题是要在每个产品组的所有数据行结束后,单独插入一行显示该组的总金额,关键在于遍历数据时跟踪当前组的状态,在组切换时输出上一组的总计。
核心思路
- 用变量跟踪当前产品组的名称和对应总金额(因为你的SQL窗口函数已经保证同一组的
total_amt值相同,所以取组内任意一行的total_amt即可) - 遍历每一行数据时,判断是否属于当前组:
- 如果不属于,先输出上一组的总计行,再切换当前组
- 如果属于,直接添加数据行
- 遍历结束后,必须手动输出最后一组的总计行(因为循环里只会在组切换时输出上一组的)
具体代码实现(以iText 7为例)
假设你已经将SQL查询结果封装成了Item实体类,包含prodId、prodName、amt、totalAmt属性:
// 1. 准备查询结果(替换成你的实际数据获取逻辑) List<Item> items = yourQueryMethod(); // 2. 初始化PDF文档和表格 PdfDocument pdfDoc = new PdfDocument(new PdfWriter("product_report.pdf")); Document doc = new Document(pdfDoc); // 创建4列的表格,第四列用于放置总计金额 Table table = new Table(UnitValue.createPercentArray(new float[]{20, 30, 25, 25})); // 3. 添加表头 table.addCell(new Cell().add("PROD_ID")); table.addCell(new Cell().add("PROD_NAME")); table.addCell(new Cell().add("AMT")); table.addCell(new Cell().add("")); // 表头第四列留空 if (!items.isEmpty()) { // 初始化当前组的跟踪变量 String currentProd = items.get(0).getProdName(); BigDecimal currentTotal = items.get(0).getTotalAmt(); for (Item item : items) { // 检测到新组时,先输出上一组的总计行 if (!item.getProdName().equals(currentProd)) { // 合并前三列显示"Total:",并靠右对齐 Cell totalLabelCell = new Cell(1, 3) .add("Total:") .setTextAlignment(TextAlignment.RIGHT); table.addCell(totalLabelCell); // 添加总金额单元格 table.addCell(new Cell().add(currentTotal.toString())); // 更新当前组信息 currentProd = item.getProdName(); currentTotal = item.getTotalAmt(); } // 添加当前数据行 table.addCell(new Cell().add(item.getProdId())); table.addCell(new Cell().add(item.getProdName())); table.addCell(new Cell().add(item.getAmt().toString())); table.addCell(new Cell().add("")); // 数据行第四列留空 } // 处理最后一组的总计行(循环里不会触发) Cell finalTotalLabel = new Cell(1, 3) .add("Total:") .setTextAlignment(TextAlignment.RIGHT); table.addCell(finalTotalLabel); table.addCell(new Cell().add(currentTotal.toString())); } // 将表格添加到文档并关闭 doc.add(table); doc.close();
额外优化建议
- 样式美化:可以给总计行设置加粗字体,比如:
PdfFont boldFont = PdfFontFactory.createFont(StandardFonts.HELVETICA_BOLD); totalLabelCell.setFont(boldFont); - 空值处理:如果
prodName可能为null,要在判断相等时做非空校验,避免空指针异常 - iText 5适配:如果你用的是iText 5版本,需要将
Table换成PdfPTable,Cell换成PdfPCell,核心逻辑保持不变
内容的提问来源于stack exchange,提问作者Maibhalsych
相关产品推荐
相关产品推荐

