首页 > 解决方案 > 如何在不知道之前的类的情况下使用 CSV HeaderColumnNameTranslateMappingStrategy

问题描述

我有一个大问题。我想将 CSV 文件映射到我的实体。这应该动态发生。我从前端获取用户的文件和映射。它包含 headerColumn、类和属性。这将通过 JSONArray 进行迭代。所以我不知道这个类,因为也许用户告诉他想让 headerColumn“abc”作为 Article.articleName,但在同一个 CSV 中,headerColumn“def”作为 Competitor.location。

我的尝试:

     List<Class> classes = new ArrayList<>();
     for (int i = 0; i < jsonArray.length(); i++) {

         Class<?> cls = Class.forName(pathToEntities + jsonArray.getJSONObject(i).get(classKey).toString());
         maps.put(cls, columnMapping);
     }

     for (int i = 0; i < classes.size(); i++) {
         Class cls = classes.get(i);
         CsvToBean<cls> csvToBean = new CsvToBean<cls>();

         columnMapping.put("LANGU", "id");
         columnMapping.put("TXTMD", "fname");
         columnMapping.put("Lname", "lname");

         HeaderColumnNameTranslateMappingStrategy<cls> strategy = new HeaderColumnNameTranslateMappingStrategy<cls>();
         strategy.setType(cls);
         strategy.setColumnMapping(columnMapping);
     }

我希望你能关注我。对于每个班级,我都想运行整个映射过程。columnMapping Map 将被赋予这个类。但是编译器无法使用它,并告诉我何时给出CsvToBeana 变量而不是类:cls cannot be resolved to a type

这里的库是 OpenCSV。但我真的不在乎使用哪个 CSV 库。我只是想让它工作。无论如何,我都会实现它们中的每一个。现在这对我来说似乎无法解决。

标签: javacsv

解决方案


您可以尝试使用instanceof来检查您从 Class.forName() 获得的实体

        CSVReader csvReader = new CSVReader(new FileReader("Simple.csv"));
        Class aClass = Class.forName("com.ishikawa.csvparser.entity.SimpleEntity");
        CsvToBean ctb = new CsvToBean();
        HashMap<String, String> columnMapping = new HashMap<>();

        HeaderColumnNameTranslateMappingStrategy headerStrategy = new HeaderColumnNameTranslateMappingStrategy();

        columnMapping.put("LANGU", "name");
        headerStrategy.setType(aClass);
        headerStrategy.setColumnMapping(columnMapping);

        ctb.setMappingStrategy(headerStrategy);
        ctb.setCsvReader(csvReader);



        List parse = ctb.parse();
        parse.stream().forEach(e->{
            if (e instanceof SimpleEntity) {
                System.out.println(((SimpleEntity)e).getName());
            }
        });

用 simple.csv

LANGU
asd
asdf

以实体为例

package com.ishikawa.csvparser.entity;

import lombok.Data;

@Data
public class SimpleEntity {

    public String name;
}

希望它可以帮助你。

upd1 如果您需要更改分隔符并将创建的 CSVParser 实例添加到 CSVReader

CSVParser parser = new CSVParserBuilder()
        .withSeparator(';')
        .withIgnoreQuotations(true)
        .build();

CSVReader csvReader = new CSVReaderBuilder(reader)
        .withSkipLines(0)
        .withCSVParser(parser)
        .build();

推荐阅读