잘 정리해보자
Spring Batch - csv파일 쓰기 (FlatFileItemWriter) 본문
csv파일 읽기에 이어 csv파일 쓰기를 구현.
csv파일 읽기 : https://choisblog.tistory.com/82
FlatFileItemWriter
: 파일을 쓰기/저장 하는 클래스
객체를 계속 실행하면 덮어쓰는 형식으로 저장이 된다. (기존의 파일을 삭제 후 같은이름으로 저장)
- 저장할 csv파일의 필드명,구분자 설정
@Bean
@StepScope
public FlatFileItemWriter<TestCsvFieldVo> writer() throws Exception{
BeanWrapperFieldExtractor<TestCsvFieldVo> extractor = new BeanWrapperFieldExtractor();
extractor.setNames(new String[] {"id","name","address"}); //필드명 설정
//line 구분값 설정
DelimitedLineAggregator<TestCsvFieldVo> lineAggreator = new DelimitedLineAggregator<>();
lineAggreator.setDelimiter(",");
lineAggreator.setFieldExtractor(extractor);
BeanWrapperFieldExtractor
: csv파일에 작성할 필드를 추출하기 위해 FieldExtractor 객체가 필요.
DelimitedLineAggregator
: csv Line을 write할 때의 구분값 설정. ( ex : (,)설정 -> 이름,나이,주소 (/) 설정 -> 이름/나이/주소 )
- 리턴할 FlatFileItemWriter 설정.
@Bean
@StepScope
public FlatFileItemWriter<TestCsvFieldVo> writer() throws Exception{
...
FlatFileItemWriter<TestCsvFieldVo> writer = new FlatFileItemWriterBuilder<TestCsvFieldVo>()
.name("csvItemWriter")
.encoding("UTF-8")
.resource(new FileSystemResource("output/test.csv")) //경로 지정
.lineAggregator(lineAggreator)
.build();
writer.afterPropertiesSet();
return writer;
}
new FileSystemResource()
: write 시, 지정할 파일 경로 설정. (해당 프로젝트 파일 기준으로 디렉토리가 없으면 생성 후, 파일을 저장한다.)
(reader에서는 resource 안의 파일을 읽기 위해 ClassPathResource 을 사용했다.)
> 프로젝트 파일안의 output파일이 생성되고 안에 test.csv파일이 생성된다.
실행 결과
: test.csv
id,name,address
1,wow,seoul_process
2,chois,incheon_process
3,lee,seoul_process
만약, writer을 다시 실행했을 때, 현재는 덮어쓰기 형식이지만 뒤에 글을 이어서 write하는 경우 .append()을 true로 설정하면 된다.
FlatFileItemWriter<TestCsvFieldVo> writer = new FlatFileItemWriterBuilder<TestCsvFieldVo>()
.name("csvItemWriter")
.encoding("UTF-8")
.resource(new FileSystemResource("output/test.csv"))
.lineAggregator(lineAggreator)
.headerCallback(writer1 -> writer1.write("id,name,address")) //header설정
.footerCallback(writer1 -> writer1.write("---------------\n")) //footer설정
.append(true)
.build();
header를 지정하려면 headerCallback, footer를 지정하려면 footerCallback 선언.
실행 결과
: test.csv
id,name,address
1,wow,seoul_process
2,chois,incheon_process
3,lee,seoul_process
---------------1,wow,seoul_process
2,chois,incheon_process
3,lee,seoul_process
---------------
1,wow,seoul_process
2,chois,incheon_process
3,lee,seoul_process
> 기존의 write된 footer에는 \n 개행처리가 없어서
---------------1,wow,seoul_process 으로 출력된다.
FlatFileItemWriter 전체 소스
@Bean
@StepScope
public FlatFileItemWriter<TestCsvFieldVo> writer() throws Exception{
//csv파일에 작성할 데이터를 추출하기 위해서 fieldExtractor 객체가 필요
BeanWrapperFieldExtractor<TestCsvFieldVo> extractor = new BeanWrapperFieldExtractor();
extractor.setNames(new String[] {"id","name","address"}); //필드명 설정
//line 구분값 설정
DelimitedLineAggregator<TestCsvFieldVo> lineAggreator = new DelimitedLineAggregator<>();
lineAggreator.setDelimiter(",");
lineAggreator.setFieldExtractor(extractor);
FlatFileItemWriter<TestCsvFieldVo> writer = new FlatFileItemWriterBuilder<TestCsvFieldVo>()
.name("csvItemWriter")
.encoding("UTF-8")
.resource(new FileSystemResource("output/test.csv")) //FileSystemResource : write할때 경로 지정
.lineAggregator(lineAggreator)
.headerCallback(writer1 -> writer1.write("id,name,address")) //header설정
.footerCallback(writer1 -> writer1.write("---------------\n")) //footer설정
.append(true)
.build();
writer.afterPropertiesSet();
return writer;
}