Java中使用SequentialWriter生成CSV时换行异常问题求助
问题
使用Jackson的SequentialWriter生成CSV文件时,遇到换行符处理问题。当前代码配置如下:
CsvMapper csvMapper = new CsvMapper(); DefaultSerializerProvider.Impl sp = new DefaultSerializerProvider.Impl(); sp.setNullValueSerializer(new CustomNullSerializer()); csvMapper.setSerializerProvider(sp); //csvMapper.enable(CsvGenerator.Feature.ALWAYS_QUOTE_STRINGS); //csvMapper.disable(CsvGenerator.Feature.ALWAYS_QUOTE_EMPTY_STRINGS); csvMapper.setDateFormat(dtFormat); try { seqW.write(new Object[]{"\r"});} catch (IOException e) {throw new UncheckedIOException(e);}
想要输出回车换行实现空行,但实际生成的CSV出现带引号的空行:
Label,"Business Rule Id","Key List",Level "20000 - ccccc-xxxxxx(INC SUBS)",ROLLPO,20000 ,"27367 - ccccc-xxxxxx",ROLLPO,27367 " /// 我不想看到这个。 " "20715 - ccccc-xxxxxx ENTITY",ROLLPO,20715 ,"20723 - ccccc-xxxxxx",ROLLPO,20723 ,,"20769 - ccccc-xxxxxx",ROLLPO,20769 ,,,"20896 - ccccc-xxxxxx-LE",ROLLPO,20896 ,,,,"50012 - ccccc-xxxxxx",ROLLPO,50012
期望的CSV格式是:
Label,"Business Rule Id","Key List",Level "20000 - ccccc-xxxxxx(INC SUBS)",ROLLPO,20000, ,"27367 - ccccc-xxxxxx",ROLLPO,27367 "20715 - ccccc-xxxxxx ENTITY",ROLLPO,20715, ,"20723 - ccccc-xxxxxx",ROLLPO,20723, ,,"20769 - ccccc-xxxxxx",ROLLPO,20769, ,,,"20896 - ccccc-xxxxxx-LE",ROLLPO,20896, ,,,,"50012 - ccccc-xxxxxx",ROLLPO,50012
解决方案
方法1:直接操作底层输出流写入换行符
跳过SequentialWriter的write()方法,直接获取底层输出流写入原始换行符,避免触发CSV字段序列化的引号包裹逻辑:
// 写入3个空行匹配需求 try { seqW.getOutput().write(System.lineSeparator() + System.lineSeparator() + System.lineSeparator()); seqW.getOutput().flush(); // 可选,确保内容立即写入文件 } catch (IOException e) { throw new UncheckedIOException(e); }
System.lineSeparator()会自动适配当前操作系统的换行规则,比硬编码\r\n更通用。
方法2:配置CSV生成器+写入空数组
如果要通过write()方法实现,需先调整配置再写入空数组:
- 禁用空字符串自动引号包裹:
csvMapper.disable(CsvGenerator.Feature.ALWAYS_QUOTE_EMPTY_STRINGS);
- 每次调用
write(new Object[]{})生成一行空行:
// 生成3个空行 try { seqW.write(new Object[]{}); seqW.write(new Object[]{}); seqW.write(new Object[]{}); } catch (IOException e) { throw new UncheckedIOException(e); }
这种方式生成的空行是符合CSV规范的逗号分隔空字段,和你期望的格式完全一致。
关键注意点
- 不要把
"\r"或"\n"作为字段值传入write(),Jackson会将其视为普通字符串字段,自动添加引号包裹,这就是你看到异常空行的原因。
内容的提问来源于stack exchange,提问作者Nesan Mano
相关产品推荐
相关产品推荐

