将 csv 文件的特定列映射到特定的 POJO 字段

mapping particular column of a csv file with particular POJO's field

我必须根据具有特定 POJO 属性的索引映射特定的 CSV 列。映射将基于 json 文件,该文件将包含 columnIndex 和属性名称,这意味着对于来自 csv 文件的特定 columnIndex,您必须映射来自 Pojo class 的特定属性。 下面是 json 文件的示例,其中显示了具有 Pojo 属性的列映射策略。

[{"index":0,"columnname":"date"},{"index":1,"columnname":"deviceAddress"},{"index":7,"columnname":"iPAddress"},{"index":3,"columnname":"userName"},{"index":10,"columnname":"group"},{"index":5,"columnname":"eventCategoryName"},{"index":6,"columnname":"message"}]

我尝试过使用 OpenCSV 库,但遇到的挑战是我无法用它读取部分专栏。如上 json 所示,您可以看到我们正在跳过索引 2 和 4 以从 CSV 文件中读取。下面是带有 openCSV 文件的代码。

public static List<BaseDataModel> readCSVFile(String filePath,List<String> columnListBasedOnIndex) {
        List<BaseDataModel> csvDataModels = null;
        File myFile = new File(filePath);
        try (FileInputStream fis = new FileInputStream(myFile)) {
            final ColumnPositionMappingStrategy<BaseDataModel> strategy = new ColumnPositionMappingStrategy<BaseDataModel>();
            strategy.setType(BaseDataModel.class);


            strategy.setColumnMapping(columnListBasedOnIndex.toArray(new String[0]));

            final CsvToBeanBuilder<BaseDataModel> beanBuilder = new CsvToBeanBuilder<>(new InputStreamReader(fis));
            beanBuilder.withMappingStrategy(strategy);

            csvDataModels = beanBuilder.build().parse();

        } catch (Exception e) {
            e.printStackTrace();
        }
}


List<ColumnIndexMapping> columnIndexMappingList = dataSourceModel.getColumnMappingStrategy();
                    List<String> columnNameList = columnIndexMappingList.stream().map(ColumnIndexMapping::getColumnname)
                            .collect(Collectors.toList());

List<BaseDataModel> DataModels = Utility
                                    .readCSVFile(file.getAbsolutePath() + File.separator + fileName, columnNameList);

我也尝试过使用 univocity,但是对于这个库,我如何映射具有特定属性的 csv。下面是代码-

CsvParserSettings settings = new CsvParserSettings();
        settings.detectFormatAutomatically(); //detects the format 
        settings.getFormat().setLineSeparator("\n");
        //extracts the headers from the input
        settings.setHeaderExtractionEnabled(true);
        settings.selectIndexes(0, 2); //rows will contain only values of columns at position 0 and 2
        CsvRoutines routines = new CsvRoutines(settings); // Can also use TSV and Fixed-width routines
        routines.parseAll(BaseDataModel.class, new File("/path/to/your.csv"));


        List<String[]> rows = new CsvParser(settings).parseAll(new File("/path/to/your.csv"), "UTF-8");

请看看在这种情况下是否有人可以帮助我。

univocity-parsers 的作者在这里。您可以在代码而不是注释中定义到 class 属性的映射。像这样:

public class BaseDataModel {
    private String a;
    private int b;
    private String c;
    private Date d;
}

然后在您的代码中,将属性映射到您需要的任何列名称:

ColumnMapper mapper = routines.getColumnMapper();
mapper.attributeToColumnName("a", "col1");
mapper.attributeToColumnName("b", "col2");
mapper.attributeToColumnName("c", "col3");
mapper.attributeToColumnName("d", "col4");

您还可以使用 mapper.attributeToIndex("d", 3); 将属性映射到给定的列索引。

希望对您有所帮助。