如何使用Spring Batch读取具有不同列数的CSV文件

时间:2017-08-04 08:25:27

标签: spring file csv spring-batch

我有一个CSV文件没有固定数量的列,如下所示:

  col1,col2,col3,col4,col5    
  val1,val2,val3,val4,val5 
  column1,column2,column3
  value1,value2,value3

有没有办法用Spring Batch读取这种CSV文件?

我试着这样做:

<bean id="ItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">

    <!-- Read a csv file -->
    <property name="resource" value="classpath:file.csv" />

    <property name="lineMapper">
        <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
            <!-- split it -->
            <property name="lineTokenizer">
                <bean
                    class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
                    <property name="names"
                        value="col1,col2,col3,col4,col5,column1,column2,column3" />
                </bean>
            </property>
            <property name="fieldSetMapper">
                <bean
                    class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
                    <property name="prototypeBeanName" value="myBean" />
                </bean>
            </property>

        </bean>
    </property>

</bean>

但结果是这个错误:

IncorrectTokenCountException stack trace

2 个答案:

答案 0 :(得分:1)

您可以使用PatternMatchingCompositeLineMapper根据模式委派每行相应的LineMapper实施。在那里,您的每个代表都会使用DelimtedLineTokenizerFieldSetMapper来相应地映射该行。

您可以在此处的文档中详细了解此信息:http://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/item/file/mapping/PatternMatchingCompositeLineMapper.html

答案 1 :(得分:0)

您的AbstractLineTokenizer#setStrict(boolean)中的

DelimitedLineTokenizer应该可以完成这项工作。

来自javadoc

  

严格标志的公共设置器。如果为true(默认值),则为number   行中的令牌数量必须与定义的令牌数量匹配(按范围,   列等)。如果为false,则使用较少的标记行   将容忍并用空列填充,并用更多行填充   令牌将被截断。

您应该将配置的这一部分更改为:

<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
    <property name="names" value="col1,col2,col3,col4,col5,column1,column2,column3" />
    <property name="strict" value="false" />
</bean>