java - 将 csv 文件的特定列与特定 POJO 的字段映射
问题描述
我必须根据具有特定 POJO 属性的索引来映射特定的 CSV 列。映射将基于包含 columnIndex 和属性名称的 json 文件,这意味着对于 csv 文件中的特定 columnIndex,您必须从 Pojo 类映射特定属性。下面是一个 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,"列名":"消息"}]
我已经尝试过使用 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);
我也尝试过单义性,但使用这个库我如何映射具有特定属性的 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 的作者在这里。您可以在代码而不是注释中定义到类属性的映射。像这样的东西:
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);
将属性映射到给定的列索引。
希望这可以帮助。
推荐阅读
- php - PHP:str_word_count 计数减去作为一个单独的词
- javascript - 在Javascript中使用wasd使对象一致地移动
- c# - 如何在 System.Diagnostic 中为 WCF 添加计时器
- python - 将列表列表转换为字典
- react-native - 在 react native 中将动态数据翻译成多种语言
- javascript - 我有一个扁平数组作为输入,我需要以树格式重建它
- laravel - 在集合中添加缺失的数据行 - 无法解释的 Laravel 行为
- java - DatePickerDialog 输出“DatePickerFragment 必须是公共静态类才能从即时状态正确重新创建”
- highcharts - 如何通过在 highcharts 甘特图中移动点图形来移动点的标签和 SVG?
- spring - Project Reactor - 如何正确实施咖啡因