如何使用Super CSV处理具有未知列数的CSV文件

时间:2014-02-09 11:37:59

标签: java csv pojo supercsv

对于一个项目,我需要处理CSV文件,在运行之前我不知道列。 CSV文件完全有效,我只需要一遍又一遍地对几个不同的文件执行简单的任务。我需要分析列的值,这就是为什么我需要使用库来处理CSV文件。为简单起见,我们假设我需要做一些简单的事情,比如将日期列附加到所有文件,无论它们有多少列。我想用Super CSV做到这一点,因为我也将库用于其他任务。

我所挣扎的更多是一个概念问题。如果我事先不知道有多少列,我不知道如何处理文件。我不知道如何定义映射任意CSV文件的POJO,或者如果我不知道文件中的哪些列和多少列,我应该如何定义Cell Processors。如何动态创建与列数匹配的Cell处理器?我如何根据CSV文件的标题定义POJO?

考虑我有两个CSV文件的情况:products.csv和address.csv。让我们假设我想在两个文件的日期列中添加一个日期列,而不必编写两个不同的方法(例如addDateColumnToProduct()和addDateColumnToAddress())来执行相同的操作。

product.csv:

name, description, price
"Apple", "red apple from Italy","2.5€" 
"Orange", "orange from Spain","3€"

address.csv:

firstname, lastname
"John", "Doe"
"Coole", "Piet"

根据CSV文件的标题信息,我如何定义映射产品CSV的POJO?细胞处理器的问题是什么?我怎么能定义一个非常简单的单元处理器,它基本上只有构造函数的适当数量的参数,例如对于product.csv

CellProcessor[] processor = new CellProcessor[] { 
    null,
    null,
    null
};

和address.csv:

CellProcessor[] processor = new CellProcessor[] { 
    null,
    null
};

这甚至可能吗?我是否在错误的轨道上实现这一目标?

编辑1:正在寻找能够处理一个文件中具有可变列的CSV文件的解决方案。我试着弄清楚是否可以在运行时处理任意CSV文件,即我是否可以仅根据运行时CSV文件中包含的头信息创建POJO。事先不知道csv文件会有多少列。

解决方案 根据@baba的答案和评论

private static void readWithCsvListReader() throws Exception {

        ICsvListReader listReader = null;
        try {
                listReader = new CsvListReader(new FileReader(fileName), CsvPreference.TAB_PREFERENCE);

                listReader.getHeader(true); // skip the header (can't be used with CsvListReader)
                int amountOfColumns=listReader.length();
                CellProcessor[] processor = new CellProcessor[amountOfColumns];
                List<Object> customerList;

                while( (customerList = listReader.read(processor)) != null ) {
                        System.out.println(String.format("lineNo=%s, rowNo=%s, customerList=%s", listReader.getLineNumber(),
                                listReader.getRowNumber(), customerList));
                }

        }
        finally {
                if( listReader != null ) {
                        listReader.close();
                }
        }
}

2 个答案:

答案 0 :(得分:3)

也许有点晚了但可能会有所帮助...

  CellProcessor[] processors=new CellProcessor[properties.size()];

  for(int i=0; i< properties.zise(); i++){
            processors[i]=new Optional();

   }
    return  processors;

答案 1 :(得分:1)

这是一个非常常见的问题,internetz上有多个教程,包括Super Csv页面:

http://supercsv.sourceforge.net/examples_reading_variable_cols.html

正如这句话所说:

  

如下图所示,您可以在调用后执行单元处理器   read()通过调用executeProcessors()方法。因为它已经完成了   阅读CSV行后,您有机会查看如何   有许多列(使用listReader.length())并提供   正确的处理器数量。