如何基于状态构建数组并统计Excel报表中产品状态数据
解决按状态分组统计产品数量的问题
你的核心问题在于使用Map<String, String[]>作为存储结构不太合适——数组的长度固定,无法动态添加同一状态下的多个产品,而且你的代码里直接把单个产品字符串放到数组的位置,本身就不符合类型要求。我们可以把Map的value类型改成List<String>,这样就能轻松收集每个状态对应的所有产品,之后再用Collections.frequency统计数量就顺理成章了。
步骤1:修改存储结构
首先把原来的Map<String, String[]>替换成Map<String, List<String>>,用来存储每个状态对应的产品列表:
// 替换原来的mapinData定义 Map<String, List<String>> statusToProductsMap = new HashMap<>();
步骤2:遍历ResultSet收集数据
在遍历ResultSet的循环中,替换掉原来的mapinData.put(dataStat,dataProd);逻辑,改成动态往对应状态的列表中添加产品:
while (rs.next()) { // 保留你原来获取dataProd和dataStat的逻辑 String dataProd = ""; String dataStat = ""; for (int column = 0; column <= columnCount - 1; column++) { String cellValue = (rs.getString(column + 1) == null ? "" : rs.getString(column + 1)); label = new Label(column, r, cellValue); excelSheet.addCell(label); if (column == colProduct - 1) { // 注意colProduct是从1开始的列数,column是0开始的索引,需减1 dataProd = cellValue; } else if (column == colStatus - 1) { dataStat = cellValue; } } // 核心修改:往对应状态的列表中添加产品 // 获取当前状态的产品列表,不存在则新建空列表 List<String> productList = statusToProductsMap.getOrDefault(dataStat, new ArrayList<>()); productList.add(dataProd); // 更新Map中的列表 statusToProductsMap.put(dataStat, productList); r++; }
注意:原来的代码中
column == colProduct存在索引匹配错误——colProduct是你从1开始计数的列号,而循环中的column是从0开始的索引,所以要改成column == colProduct - 1,否则会匹配错误的列。
步骤3:统计数量并生成Excel汇总
遍历上面的Map,对每个状态下的产品列表统计数量,然后写入Excel:
// 定义当前汇总行的起始位置,比如在原有数据之后空几行 int currentSummaryRow = r + 2; for (Map.Entry<String, List<String>> entry : statusToProductsMap.entrySet()) { String status = entry.getKey(); List<String> products = entry.getValue(); // 写入"summary [status]"标题 Label summaryTitle = new Label(0, currentSummaryRow, "summary " + status); excelSheet.addCell(summaryTitle); currentSummaryRow++; // 写入表头 Label prodHeader = new Label(0, currentSummaryRow, "product_code"); Label sumHeader = new Label(1, currentSummaryRow, "sum"); excelSheet.addCell(prodHeader); excelSheet.addCell(sumHeader); currentSummaryRow++; // 去重获取当前状态下的所有唯一产品 Set<String> uniqueProducts = new HashSet<>(products); for (String product : uniqueProducts) { // 统计产品出现次数 int count = Collections.frequency(products, product); // 写入Excel行 Label prodCell = new Label(0, currentSummaryRow, product); Label countCell = new Label(1, currentSummaryRow, String.valueOf(count)); excelSheet.addCell(prodCell); excelSheet.addCell(countCell); currentSummaryRow++; } // 添加空行分隔不同状态的汇总 currentSummaryRow++; }
为什么这样改?
List<String>可以动态添加元素,完美适配每个状态下产品数量不确定的场景,而数组做不到这一点。getOrDefault方法简化了"判断列表是否存在,不存在则新建"的逻辑,比手动写if (statusToProductsMap.containsKey(dataStat))更简洁。- 原来的代码中
mapinData.put(dataStat, dataProd)会覆盖同一状态下的之前的产品,导致最后只保留最后一个产品,换成List后就能收集所有产品了。
内容的提问来源于stack exchange,提问作者ikiSiTamvaaan
相关产品推荐
相关产品推荐

