Spring Batch使用FlatFileItemWriter导出CSV列异常求助
Spring Batch FlatFileItemWriter导出CSV数据全在同一列的解决方法
问题排查与修复步骤
1. 检查属性名称与Test类的匹配性
BeanWrapperFieldExtractor的setNames方法传入的属性名必须与Test类的实际属性名(或getter方法对应的属性名)完全一致。Java中通常属性名采用小驼峰命名(比如id而非Id),如果你的Test类属性是:
public class Test { private Long id; private String typeTest1; private String typeTest2; // 对应的getter方法:getId(), getTypeTest1(), getTypeTest2() }
那setNames应该改为:
beanWrapperFieldExtractor.setNames(new String[] {"id", "typeTest1", "typeTest2"});
(注意首字母小写,BeanWrapper会自动匹配对应的getter方法)
2. 添加表头配置(解决表头也在同一列的问题)
如果需要导出表头,需要给FlatFileItemWriter设置HeaderCallback,用同样的分隔符生成表头行:
flatFileItemWriter.setHeaderCallback(writer -> { DelimitedLineAggregator<String> headerAggregator = new DelimitedLineAggregator<>(); headerAggregator.setDelimiter(","); headerAggregator.setFieldExtractor(items -> items); writer.write(headerAggregator.aggregate(new String[] {"ID", "TypeTest1", "TypeTest2"})); });
3. 完善FlatFileItemWriter的初始化(可选但推荐)
使用FlatFileItemWriterBuilder可以让配置更清晰,避免手动调用open/write/close时的潜在问题:
public FlatFileItemWriter<Test> writeFile(List<Test> tests) throws Exception { FlatFileItemWriter<Test> flatFileItemWriter = new FlatFileItemWriterBuilder<Test>() .resource(new FileSystemResource("/data/outputData.csv")) .lineAggregator(getDelimitedLineAggregator()) .headerCallback(writer -> { DelimitedLineAggregator<String> headerAggregator = new DelimitedLineAggregator<>(); headerAggregator.setDelimiter(","); headerAggregator.setFieldExtractor(items -> items); writer.write(headerAggregator.aggregate(new String[] {"ID", "TypeTest1", "TypeTest2"})); }) .append(false) // 覆盖原有文件,若需要追加设为true .build(); flatFileItemWriter.open(new ExecutionContext()); flatFileItemWriter.write(tests); flatFileItemWriter.close(); return flatFileItemWriter; }
4. 验证分隔符是否生效
确保没有其他代码修改了分隔符,比如如果CSV查看工具(比如Excel)默认的分隔符不是逗号,可能会显示在同一列。可以用文本编辑器打开导出的CSV文件,确认每行数据是否用逗号分隔开:
ID,TypeTest1,TypeTest2 1,value1,value2 2,value3,value4
如果文本里是正确分隔的,那只是查看工具的设置问题,调整工具的分隔符即可。
完整修正后的代码示例
import org.springframework.batch.item.file.FlatFileItemWriter; import org.springframework.batch.item.file.builder.FlatFileItemWriterBuilder; import org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor; import org.springframework.batch.item.file.transform.DelimitedLineAggregator; import org.springframework.core.io.FileSystemResource; import org.springframework.batch.item.ExecutionContext; import java.util.List; public class CsvExporter { public FlatFileItemWriter<Test> writeFile(List<Test> tests) throws Exception { FlatFileItemWriter<Test> flatFileItemWriter = new FlatFileItemWriterBuilder<Test>() .resource(new FileSystemResource("/data/outputData.csv")) .lineAggregator(getDelimitedLineAggregator()) .headerCallback(writer -> { DelimitedLineAggregator<String> headerAggregator = new DelimitedLineAggregator<>(); headerAggregator.setDelimiter(","); headerAggregator.setFieldExtractor(items -> items); writer.write(headerAggregator.aggregate(new String[] {"ID", "TypeTest1", "TypeTest2"})); }) .append(false) .build(); flatFileItemWriter.open(new ExecutionContext()); flatFileItemWriter.write(tests); flatFileItemWriter.close(); return flatFileItemWriter; } private DelimitedLineAggregator<Test> getDelimitedLineAggregator() { BeanWrapperFieldExtractor<Test> beanWrapperFieldExtractor = new BeanWrapperFieldExtractor<>(); // 确保这里的属性名与Test类的属性完全匹配 beanWrapperFieldExtractor.setNames(new String[] {"id", "typeTest1", "typeTest2"}); // 可选:如果属性可能为null,设置默认值 // beanWrapperFieldExtractor.setNullValue(""); DelimitedLineAggregator<Test> aggregator = new DelimitedLineAggregator<>(); aggregator.setDelimiter(","); aggregator.setFieldExtractor(beanWrapperFieldExtractor); return aggregator; } // 示例Test类 public static class Test { private Long id; private String typeTest1; private String typeTest2; public Test(Long id, String typeTest1, String typeTest2) { this.id = id; this.typeTest1 = typeTest1; this.typeTest2 = typeTest2; } // 必须提供对应的getter方法 public Long getId() { return id; } public String getTypeTest1() { return typeTest1; } public String getTypeTest2() { return typeTest2; } } }
内容的提问来源于stack exchange,提问作者testyahoo
相关产品推荐
相关产品推荐

