4

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

我正在努力解决的问题更多的是一个概念问题。如果我事先不知道有多少列,我不确定如何处理这些文件。我不确定应该如何定义映射任意 CSV 文件的 POJO,或者如果我不知道文件中有哪些列和多少列,我应该如何定义单元处理器。如何动态创建与列数匹配的 Cell 处理器?例如,我将如何根据 CSV 文件的标题定义 POJO?

考虑我有两个 CSV 文件的情况:products.csv 和 address.csv。假设我想为两个文件添加一个带有今天日期的日期列,而不必编写两种不同的方法(例如 addDateColumnToProduct() 和 addDateColumnToAddress())来做同样的事情。

产品.csv:

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

地址.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();
                }
        }
}
4

2 回答 2

3

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

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

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

   }
    return  processors;
于 2014-11-27T21:50:04.510 回答
1

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

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

正如这一行所说:

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

于 2014-02-09T11:42:50.477 回答