需要将多个columNames映射到Univocity中的单个字段

class MyPOJO implements Serializable { private static final long serialVersionUID = 1L; @Parsed(field = "UniqueCode") private String code; @Parsed(field = "Name") private String name; @Parsed(field = "dogId") private String someOtherId; //------Getters and Setters------- public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSomeOtherId() { return someOtherId; } public void setSomeOtherId(String someOtherId) { this.someOtherId = someOtherId; } } 

现在我需要映射单个字段,例如someOtherId具有来自不同csv文件的多个标题名称(例如:“dogId”,“catId”,“cowId”等)。 因此,假设在文件1.csv中 ,名为dogId的标题列应映射到POJO字段someOtherId而在文件2.csv中 ,标题catId应映射到相同的字段,即someOtherId 。 可能吗? 怎么样?

如果具有someOtherId值的列始终位于同一位置,则无论您使用哪个文件,都可以轻松解析此问题。

 class MyPOJO implements Serializable { private static final long serialVersionUID = 1L; @Parsed(field = "UniqueCode") private String code; @Parsed(field = "Name") private String name; @Parsed(index = 2) //anything goes here, "catId", "cowId", etc private String someOtherId; ... } 

如果每个输入文件中的列位置不同,您可以实现自己的行处理器。 我创建了以下可能适合您的实现。 它实质上将可能的标头映射到索引。 这些索引应与您的类中注释的索引匹配。

我会打破细节,帮助你理解我的所作所为。

首先为POJO的每个字段分配一个索引:

  @Parsed(index = 0) private String code; @Parsed(index = 1) private String name; @Parsed(index = 2) //cowId, dogId or catId or anything else private String someOtherId; 

围绕现有的BeanProcessor实现创建一个包装器:

 public class MyBeanProcessor extends AbstractRowProcessor{ //here's the wrapped bean processor. private final BeanListProcessor processor; //we need a LinkedHashMap here to keep the the correct ordering. private final LinkedHashMap headersToCapture; public MyBeanProcessor(Class beanType, LinkedHashMap headersToCapture){ processor = new BeanListProcessor(beanType); this.headersToCapture = headersToCapture; } // work with parsed headers to find out what is in the input @Override public void rowProcessed(String[] inputRow, ParsingContext context) { //... more details later } @Override public void processEnded(ParsingContext context) { processor.processEnded(context); } public List getBeans(){ return processor.getBeans(); } } 

此自定义行处理器的预期用途:

 //keys are possible headers, and values are the indexes where each header will be mapped to: Map headerPositions = new LinkedHashMap(); headerPositions.put("UniqueCode", 0); headerPositions.put("Name", 1); headerPositions.put("dogId", 2); headerPositions.put("catId", 2); headerPositions.put("cowId", 2); CsvParserSettings settings = new CsvParserSettings(); //we want headers settings.setHeaderExtractionEnabled(true); //let's use the custom row processor: MyBeanProcessor processor = new MyBeanProcessor(MyPOJO.class, headerPositions); settings.setRowProcessor(processor); CsvParser parser = new CsvParser(settings); parser.parse(); List myPojos = processor.getBeans(); 

rowProcessed方法的实现:

  private int[] headerIndexes = null; private String[] row = null; @Override public void rowProcessed(String[] inputRow, ParsingContext context) { if(headerIndexes == null){ //initializes the indexes to capture processor.processStarted(context); String[] parsedHeaders = context.headers(); LinkedHashSet indexes = new LinkedHashSet(); for(String headerToCapture : headersToCapture.keySet()){ int headerIndex = ArgumentUtils.indexOf(parsedHeaders, headerToCapture); if(headerIndex != -1){ indexes.add(headerIndex); } } headerIndexes = ArgumentUtils.toIntArray(indexes); row = new String[indexes.size()]; //creates a reusable row with the number of columns captured } //once the input format is known, we can collect the values from the expected positions: for(int i = 0; i < headerIndexes.length; i++){ int indexToCapture = headerIndexes[i]; if(indexToCapture < inputRow.length){ row[i] = inputRow[indexToCapture]; } else { row[i] = null; } } //and submit a row with the values in the correct places to the actual bean processor processor.rowProcessed(row, context); } 

我在本地测试了这个,并且无论头部位于何处,都会按预期解析以下输入:

输入1

 UniqueCode,T,name,dogId 1,99,2,3 

产生

 MyPOJO{code='1', name='2', someOtherId='3'} 

输入2

 cowId,Z,UniqueCode,T,name 4,99,5,99,6 

产生

 MyPOJO{code='5', name='6', someOtherId='4'} 

希望这可以帮助。