【问题标题】:How to add spaces before delimiter for each column using spring batch?如何使用弹簧批处理在每列的分隔符之前添加空格?
【发布时间】:2019-04-24 05:13:06
【问题描述】:

使用spring批处理从db写入csv文件时,我需要在每列的分隔符之前根据条件添加空格。

例如,我在 csv 文件中需要间距

Column1;Column2;Column3;Column4
AI22;FIENC234DK;EDEJJEDK;JEND4
OR2 ;JFJRN3D   ;DEDERF3E;FEF
EK3R;DJE3DJJEJE;JDJENEJ ;3NEN3

我已经展示了当前运行的代码块

  @Bean
ItemReader<CdVehicle> databaseToCsvItemReader() {
    JdbcCursorItemReader<CdVehicle> databaseReader = new JdbcCursorItemReader<>();

    databaseReader.setDataSource(dataSource);
    databaseReader.setSql(QUERY_FIND_FRIENDS);
    databaseReader.setRowMapper(new BeanPropertyRowMapper<>(CdVehicle.class));

    return databaseReader;
}
@Bean
ItemWriter<CdVehicle> databaseToCsvItemWriter() {
    FlatFileItemWriter<CdVehicle> csvFileWriter = new FlatFileItemWriter<>();

    String exportFileHeader = "CV20VEHID;CV20RFDPR;CV20USAGE;CV20CRVEH;CV20PERID;CV20SITE;CV27PROJ;CV27TYCAI;CV27PHASE;CV27MILLE;CV27CRV;O;CV20DTECL;CV20TEINT;CV20PRINCIPALE;CV20SECONDAIRE;CV20CRBIS;CV36TYPRX";
    StringHeaderWriter headerWriter = new StringHeaderWriter(exportFileHeader);
    csvFileWriter.setHeaderCallback(headerWriter);
    String userhome = System.getProperty("user.home");
    String exportFilePath = userhome + "/tmp/cdv.txt";
    csvFileWriter.setResource(new FileSystemResource(exportFilePath));

    LineAggregator<CdVehicle> lineAggregator = newPersonLineAggregator();
    csvFileWriter.setLineAggregator(lineAggregator);

    return csvFileWriter;
}

@Bean
public Step databaseToCsvStep() {
    return stepBuilderFactory.get("databaseToCsvStep")
            .<CdVehicle, CdVehicle>chunk(100)
            .reader(databaseToCsvItemReader())
            .writer(databaseToCsvItemWriter())
            .build();
}

@Bean
Job databaseToCsvJob() {
    return jobBuilderFactory.get("databaseToCsvJob")
            .incrementer(new RunIdIncrementer())
            .flow(databaseToCsvStep())
            .end()
            .build();
}

private LineAggregator<CdVehicle> newPersonLineAggregator() {
    DelimitedLineAggregator<CdVehicle> lineAggregator = new DelimitedLineAggregator<>();
    lineAggregator.setDelimiter(";");
    FieldExtractor<CdVehicle> fieldExtractor = newPersonFieldExtractor();
    lineAggregator.setFieldExtractor(fieldExtractor);
    return lineAggregator;
}

private FieldExtractor<CdVehicle> newPersonFieldExtractor() {
    BeanWrapperFieldExtractor<CdVehicle> extractor = new BeanWrapperFieldExtractor<>();
    extractor.setNames(new String[] {"CV20VEHID","CV20RFDPR","CV20USAGE","CV20CRVEH","CV20DTAPP","CV20PERID","CV20SITE","CV27PROJ","CV27TYCAI","CV27PHASE","CV27MILLE","CV27CRV","CV27TYMOT","O","CV20DTECL","CV20TEINT","CV20PRINCIPALE", "CV20SECONDAIRE","CV20CRBIS","CV36TYPRX"});
    return extractor;
}

运行 spring 批处理作业后,我得到的结果例如

    Column1;Column2;Column3;Column4
    AI22;FIENC234DK;EDEJJEDK;JEND4
    OR2;JFJRN3D;DEDERF3E;FEF
    EK3R;DJE3DJJEJE;JDJENEJ;3NEN3

为了实现间距如何逐列检查条件。有人知道如何在迭代期间通过列标题名称条件检查并在定界符之前留出空间。

【问题讨论】:

  • 您或许应该问一下为什么在类似 CSV 的文件中需要某种固定宽度,这并不常见,因为无论如何都有分隔符 ;...
  • 您是否考虑过使用FormatterLineAggregator 而不是DelimitedLineAggregator?这将更适合您的用例 IMO。

标签: spring-batch


【解决方案1】:

您可以通过使用 Spring Batch FormatterLineAggregator 来利用 String Formatter 语法。只需将您现有的 LineAggregator 实现替换为以下内容:

private LineAggregator<CdVehicle> newPersonLineAggregator() {
    FormatterLineAggregator<CdVehicle> lineAggregator = new FormatterLineAggregator<>();
    lineAggregator.setFieldExtractor(newPersonFieldExtractor());
    lineAggregator.setFormat("%-4s;%-10s;%-8d;%-5s");
    return lineAggregator;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-20
    相关资源
    最近更新 更多