You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iTextPDF实现按产品分组展示并在组末显示总金额问题

解决iTextPDF分组后添加组总计行的问题

我正好碰到过类似的需求,给你梳理个靠谱的实现思路和代码!你的核心问题是要在每个产品组的所有数据行结束后,单独插入一行显示该组的总金额,关键在于遍历数据时跟踪当前组的状态,在组切换时输出上一组的总计。

核心思路

  1. 用变量跟踪当前产品组的名称和对应总金额(因为你的SQL窗口函数已经保证同一组的total_amt值相同,所以取组内任意一行的total_amt即可)
  2. 遍历每一行数据时,判断是否属于当前组:
    • 如果不属于,先输出上一组的总计行,再切换当前组
    • 如果属于,直接添加数据行
  3. 遍历结束后,必须手动输出最后一组的总计行(因为循环里只会在组切换时输出上一组的)

具体代码实现(以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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:09:53