将多个 CSV 映射到单个 POJO



我有很多具有不同列标题的CSV文件。目前,我正在读取这些csv文件,并根据它们的列标题将它们映射到不同的POJO类。因此,某些CSV文件具有大约100个列标题,这使得创建POJO类变得困难。

那么是否有任何技术可以使用单个 pojo,因此在读取这些 csv 文件时可以映射到单个 POJO 类,或者我应该逐行读取 CSV 文件并相应地解析,或者我应该在运行时创建 POJO(javaassist)?

如果我正确理解了您的问题,您可以使用 uniVocity 解析器来处理这个问题并在地图中获取数据:

//First create a configuration object - there are many options 
//available and the tutorial has a lot of examples
CsvParserSettings settings = new CsvParserSettings();
settings.setHeaderExtractionEnabled(true);
CsvParser parser = new CsvParser(settings);
parser.beginParsing(new File("/path/to/your.csv"));
// you can also apply some transformations:
// NULL year should become 0000
parser.getRecordMetadata().setDefaultValueOfColumns("0000", "Year");
// decimal separator in prices will be replaced by comma
parser.getRecordMetadata().convertFields(Conversions.replace("\.00", ",00")).set("Price");
Record record;
while ((record = parser.parseNextRecord()) != null) {
     Map<String, String> map = record.toFieldMap(/*you can pass a list of column names of interest here*/);
     //for performance, you can also reuse the map and call record.fillFieldMap(map);
}

或者,您甚至可以在一个步骤中解析文件并获取不同类型的 bean。以下是您的操作方法:

CsvParserSettings settings = new CsvParserSettings();
//Create a row processor to process input rows. In this case we want
//multiple instances of different classes:
MultiBeanListProcessor processor = new MultiBeanListProcessor(TestBean.class, AmountBean.class, QuantityBean.class);
// we also need to grab the headers from our input file
settings.setHeaderExtractionEnabled(true);
// configure the parser to use the MultiBeanProcessor
settings.setRowProcessor(processor);
// create the parser and run
CsvParser parser = new CsvParser(settings);
parser.parse(new File("/path/to/your.csv"));
// get the beans:
List<TestBean> testBeans = processor.getBeans(TestBean.class);
List<AmountBean> amountBeans = processor.getBeans(AmountBean.class);
List<QuantityBean> quantityBeans = processor.getBeans(QuantityBean.class);

在此处和此处查看示例

如果数据太大,并且无法将所有内容保存在内存中,则可以改用 MultiBeanRowProcessor 逐行流式传输输入。该方法rowProcessed(Map<Class<?>, Object> row, ParsingContext context)将为您提供为当前行中的每个类创建的实例映射。在方法中,只需调用:

AmountBean amountBean = (AmountBean) row.get(AmountBean.class);
QuantityBean quantityBean = (QuantityBean) row.get(QuantityBean.class);
...
//perform something with the instances parsed in a row.

希望这有帮助。

免责声明:我是这个库的作者。它是开源和免费的(Apache 2.0许可证)

对我来说

,在这种情况下创建一个POJO类不是一个好主意。因为列数和文件数都不是恒定的。因此,最好使用更动态的东西,您不必在很大程度上更改代码来支持更多的列或文件。

我会为给定的csv文件进行List(或MapMap List<Map<>>。其中,每个map表示 csv 文件中的一行,其中 key 作为列名。

您可以轻松地将其扩展到多个csv文件。

最新更新