使用Apache Commons CSV的CSVPrinter打印时整数值出现在新行问题
Apache Commons CSV 数值类字符串拆行问题分析与修复
问题原因
- 核心原因是1.7版本以下的Apache Commons CSV存在已知bug,
printRecords方法处理List<String[]>类型参数时,会错误将包含纯数字的字符串元素识别为新记录的开头,导致行拆分。 - 次要原因为
CSVFormat.EXCEL的默认配置会继承运行环境的区域设置,部分区域下默认分隔符、行结束符不符合预期,也可能触发输出异常。
修复方案
方案1:升级依赖版本
直接将Apache Commons CSV依赖升级到1.7及以上的稳定版本,该版本已修复printRecords的数组处理bug,原业务代码无需修改即可正常输出预期结果。
方案2:修改代码适配旧版本
如果不方便升级依赖,可以通过显式指定CSV格式配置、逐行输出记录的方式规避bug,修改后代码如下:
import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.QuoteMode; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; import java.util.List; public void printValues(Writer writer) throws IOException { List<String[]> values = new ArrayList<>(); String[] someValues = new String[]{"ABC","XYZ","123","PQR"}; values.add(someValues); // 显式固定CSV格式参数,避免环境配置影响 CSVFormat csvFormat = CSVFormat.EXCEL.builder() .setDelimiter(',') .setRecordSeparator("\n") .setQuoteMode(QuoteMode.MINIMAL) .build(); // 使用try-with-resources自动处理资源关闭和内容flush try (CSVPrinter printer = new CSVPrinter(writer, csvFormat)) { for (String[] record : values) { printer.printRecord(record); } } }
方案3:转换数组为List规避解析bug
也可以将待输出的String数组转换为List集合后再传入printRecords,规避旧版本对数组类型参数的解析异常:
printer.printRecords(values.stream().map(Arrays::asList).collect(Collectors.toList()));
内容的提问来源于stack exchange,提问作者user3601499
相关产品推荐
相关产品推荐

