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

Java导出Excel数据到TXT时totAmount值错位问题求助

解决Java Excel汇总金额写入txt时第一行金额错误的问题

问题根源

你的代码大概率是在切换账单时先输出了初始值为0的汇总行,之后才累加该账单的金额,导致第一行的totAmount用了初始值而非实际汇总结果。

调整方案:先汇总,再输出

方案1:先全量汇总再写入(更简洁)

先用Map存储每个Bill对应的累计Amount,遍历完所有Excel行后,再将Map中的内容写入txt:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelSummary {
    public static void main(String[] args) throws Exception {
        // 1. 读取Excel并汇总金额
        Map<String, BigDecimal> billAmountMap = new HashMap<>();
        try (Workbook workbook = new XSSFWorkbook("你的Excel文件路径.xlsx")) {
            Sheet sheet = workbook.getSheetAt(0);
            for (Row row : sheet) {
                // 跳过表头行,假设表头在第0行
                if (row.getRowNum() == 0) continue;
                
                String bill = row.getCell(0).getStringCellValue(); // 假设Bill在第1列
                BigDecimal amount = BigDecimal.valueOf(row.getCell(1).getNumericCellValue()); // Amount在第2列
                
                // 累加金额:如果Map中已有该Bill,就相加;否则存入初始值
                billAmountMap.put(bill, billAmountMap.getOrDefault(bill, BigDecimal.ZERO).add(amount));
            }
        }

        // 2. 写入HVEN.txt文件
        try (BufferedWriter writer = new BufferedWriter(new FileWriter("HVEN.txt"))) {
            for (Map.Entry<String, BigDecimal> entry : billAmountMap.entrySet()) {
                // 按需求格式化金额,比如保留1位小数,用逗号作为分隔符
                String formattedAmount = entry.getValue().setScale(1, BigDecimal.ROUND_HALF_UP).toString().replace(".", ",");
                writer.write(String.format("Bill: %s, totAmount: %s%n", entry.getKey(), formattedAmount));
            }
        }
    }
}

方案2:逐行遍历并实时处理(适合大文件,减少内存占用)

如果Excel文件很大,不想一次性加载所有数据,可以逐行处理,切换Bill时输出上一个Bill的汇总结果:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.math.BigDecimal;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelSummary {
    public static void main(String[] args) throws Exception {
        String currentBill = null;
        BigDecimal currentTotal = BigDecimal.ZERO;
        
        try (Workbook workbook = new XSSFWorkbook("你的Excel文件路径.xlsx");
             BufferedWriter writer = new BufferedWriter(new FileWriter("HVEN.txt"))) {
            
            Sheet sheet = workbook.getSheetAt(0);
            for (Row row : sheet) {
                if (row.getRowNum() == 0) continue; // 跳过表头
                
                String bill = row.getCell(0).getStringCellValue();
                BigDecimal amount = BigDecimal.valueOf(row.getCell(1).getNumericCellValue());
                
                if (currentBill == null) {
                    // 初始化第一个Bill
                    currentBill = bill;
                    currentTotal = currentTotal.add(amount);
                } else if (!currentBill.equals(bill)) {
                    // 切换Bill时,先输出上一个Bill的汇总
                    String formattedAmount = currentTotal.setScale(1, BigDecimal.ROUND_HALF_UP).toString().replace(".", ",");
                    writer.write(String.format("Bill: %s, totAmount: %s%n", currentBill, formattedAmount));
                    
                    // 重置当前Bill和累计金额
                    currentBill = bill;
                    currentTotal = amount;
                } else {
                    // 同一Bill,累加金额
                    currentTotal = currentTotal.add(amount);
                }
            }
            
            // 处理最后一个Bill的汇总
            if (currentBill != null) {
                String formattedAmount = currentTotal.setScale(1, BigDecimal.ROUND_HALF_UP).toString().replace(".", ",");
                writer.write(String.format("Bill: %s, totAmount: %s%n", currentBill, formattedAmount));
            }
        }
    }
}

关键调整点

  1. 避免提前输出初始值:确保只有在收集完当前Bill的所有金额后,才写入该行的汇总结果
  2. 金额格式化:按照需求将BigDecimal转换为带逗号分隔的格式(比如254.5转成254,5)
  3. 边界处理:别忘了处理Excel的表头行,以及最后一个Bill的汇总输出

内容的提问来源于stack exchange,提问作者Serenity

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 19:05:15