Java 需要将多个列映射到Univocity中的单个字段
现在我需要映射一个字段,例如someOtherId,它具有来自不同csv文件的多个标题名(例如:“dogId”、“catId”、“cowId”等)。因此,假设在文件1.csv中,名为Java 需要将多个列映射到Univocity中的单个字段,java,csv,annotations,Java,Csv,Annotations,现在我需要映射一个字段,例如someOtherId,它具有来自不同csv文件的多个标题名(例如:“dogId”、“catId”、“cowId”等)。因此,假设在文件1.csv中,名为dogId的标题列应映射到POJO字段someOtherId,而在文件2.csv中,标题catId应映射到同一字段,即someOtherId。可能吗?如何解析?如果具有someOtherId值的列始终位于同一位置,则无论您使用的是哪一个文件,都可以轻松解析此内容 class MyPOJO implements Ser
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(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;
}
}
如果每个输入文件中的列位置不同,则可以实现自己的行处理器。我创建了以下可能适用于您的实现。它本质上是将可能的头映射到索引。这些索引应该与类中注释的索引匹配
我会把细节分解,帮助你理解我做了什么
首先为POJO的每个字段分配索引:
围绕现有BeanProcessor实现创建包装:
我在本地测试了这一点,并按照预期解析了以下输入,无论标头位于何处:
输入1
产生
UniqueCode,T,name,dogId
1,99,2,3
cowId,Z,UniqueCode,T,name
4,99,5,99,6
输入2
产生
UniqueCode,T,name,dogId
1,99,2,3
cowId,Z,UniqueCode,T,name
4,99,5,99,6
希望这能有所帮助。不幸的是,索引不总是在同一列中。但我认为自定义行处理器可以工作。检查可以工作,但有一些小问题,例如如果不将已注释的字段放入headerPositions映射中,即使有设置,也不会显示。setHeaderExtractionEnabled(true);如果注释@Parsed(field=“”)只需要一些逗号分隔的字段就好了,因为这是一个真实的场景,使用POJO从不同的CSV映射多个字段。感谢您的建议,我将看看是否可以在版本2.1.0中创建对此的内置支持。如果你认为答案有助于解决你的问题,请接受。祝你一切顺利!
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<Integer> indexes = new LinkedHashSet<Integer>();
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);
}
UniqueCode,T,name,dogId
1,99,2,3
MyPOJO{code='1', name='2', someOtherId='3'}
cowId,Z,UniqueCode,T,name
4,99,5,99,6
MyPOJO{code='5', name='6', someOtherId='4'}