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

Apache Commons CSVPrinter输出Double值自动转科学计数法如何解决

问题根因

你遇到的问题本质是Double类默认的toString()方法逻辑导致的:当数值绝对值小于1e-3或者大于等于1e7时,会自动返回科学计数法格式的字符串,Commons CSV的printRecords方法默认调用元素的toString()方法做序列化,所以会输出科学计数法。

可用解决方案

方案1:遍历记录手动格式化Double字段(兼容性最好)

不要直接调用printRecords传入整个列表,逐条处理每一条记录,对Double类型字段用DecimalFormat或String.format转成非科学计数法字符串后再打印,示例代码:

// 先定义格式化器,按需调整保留小数位数,这里示例保留最多9位小数,不会补末尾0
DecimalFormat decimalFormat = new DecimalFormat("0.#########");
decimalFormat.setGroupingUsed(false); // 关闭千位分隔符,避免出现逗号分隔的数值

try (BufferedWriter bufferedWriter = Files.newBufferedWriter(Paths.get(fileName));
     CSVPrinter csvPrinter = CSVFormat.DEFAULT
             .withEscape(Character.MIN_VALUE)
             .withQuoteMode(QuoteMode.NONE)
             .withHeader(HEADERS)
             .withIgnoreHeaderCase()
             .withTrim()
             .print(bufferedWriter)) {

    // 遍历原list逐条打印
    for (Object record : list) {
        // 替换为你实际的业务对象字段读取逻辑
        YourDataRow row = (YourDataRow) record;
        csvPrinter.print(row.getNormalField());
        // 仅对Double字段做手动格式化
        csvPrinter.print(decimalFormat.format(row.getDoubleField()));
        // 其余字段按实际需求处理
        csvPrinter.println(); // 结束当前行
    }
}

方案2:提前转换字段类型

如果不想改打印逻辑,可以在构造输入list的阶段,就把所有Double类型的字段提前格式化为符合要求的字符串,再把处理后的列表传给printRecords即可,不需要调整CSVPrinter的原有配置。

方案3:使用Commons CSV 1.10+版本的类型转换器(最简配置)

如果你用的是1.10及以上版本的Commons CSV,可以直接注册Double类型的全局转换器,不需要修改遍历逻辑:

DecimalFormat decimalFormat = new DecimalFormat("0.#########");
decimalFormat.setGroupingUsed(false);

try (BufferedWriter bufferedWriter = Files.newBufferedWriter(Paths.get(fileName));
     CSVPrinter csvPrinter = CSVFormat.DEFAULT
             .withEscape(Character.MIN_VALUE)
             .withQuoteMode(QuoteMode.NONE)
             .withHeader(HEADERS)
             .withIgnoreHeaderCase()
             .withTrim()
             // 注册Double类型转换器,全局生效
             .withConverter(Double.class, (value, format) -> decimalFormat.format(value))
             .print(bufferedWriter)) {

    csvPrinter.printRecords(list);
}

额外提示:你原代码里用了try-with-resources语法声明bufferedWriter和csvPrinter后,不需要手动调用flush和close方法,资源会在try块结束后自动关闭,手动调用属于冗余逻辑还可能引发异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:09:07