OpenCSV 4.6を使用してBeanをCSVファイルに書き込むときに、すべてのヘッダーが大文字に変更されます。 Beanには@CsvBindByNameアノテーションがありますが、大文字に変更されています。
Java Bean:
public class ProjectInfo implements Serializable {
@CsvBindByName(column = "ProjectName",required = true)
private String projectName;
@CsvBindByName(column = "ProjectCode",required = true)
private String projectCode;
@CsvBindByName(column = "Visibility",required = true)
private String visibility;
//setters and getters
}
主な方法
public static void main(String[] args) throws IOException {
Collection<Serializable> projectInfos = getProjectsInfo();
try(BufferedWriter writer = new BufferedWriter(new FileWriter("test.csv"))){
StatefulBeanToCsvBuilder builder = new StatefulBeanToCsvBuilder(writer);
StatefulBeanToCsv beanWriter = builder
.withSeparator(';')
.build();
try {
beanWriter.write(projectInfos.iterator());
writer.flush();
} catch (CsvDataTypeMismatchException | CsvRequiredFieldEmptyException e) {
throw new RuntimeException("Failed to download admin file");
}
}
}
期待される結果:
"ProjectCode";"ProjectName";"Visibility"
"ANY";"Country DU";"1"
"STD";"Standard";"1"
"TST";"Test";"1"
"CMM";"CMMTest";"1"
実際の結果:
"PROJECTCODE";"PROJECTNAME";"VISIBILITY"
"ANY";"Country DU";"1"
"STD";"Standard";"1"
"TST";"Test";"1"
"CMM";"CMMTest";"1"
このメソッドを汎用ソリューションとして構築する必要があるため、ColumnMappingStrategyを使用するオプションがありません。ヘッダーをそのまま書く方法を誰かに提案してもらえますか?
実際には、 HeaderColumnNameMappingStrategyは toUpperCase()を使用して、フィールド名を格納および取得します。カスタムフィールド名を使用するには、フィールドに@CsvBindByNameアノテーションを付ける必要があります
@CsvBindByName(column = "Partner Code" )
private String partnerCode;
上記の理由により、デフォルトではPARTNERCODEに大文字になります。したがって、それを制御するには、 HeaderColumnNameTranslateMappingStrategy を実装するクラスを作成する必要があります。 csv 5.0とJava8で、私はこのように実装しました
import Java.lang.reflect.Field;
import Java.util.HashMap;
import Java.util.Map;
import com.opencsv.bean.CsvBindByName;
import com.opencsv.bean.HeaderColumnNameTranslateMappingStrategy;
import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
public class AnnotationStrategy<T> extends HeaderColumnNameTranslateMappingStrategy<T> {
Map<String, String> columnMap = new HashMap<>();
public AnnotationStrategy(Class<? extends T> clazz) {
for (Field field : clazz.getDeclaredFields()) {
CsvBindByName annotation = field.getAnnotation(CsvBindByName.class);
if (annotation != null) {
columnMap.put(field.getName().toUpperCase(), annotation.column());
}
}
setType(clazz);
}
@Override
public String getColumnName(int col) {
String name = headerIndex.getByPosition(col);
return name;
}
public String getColumnName1(int col) {
String name = headerIndex.getByPosition(col);
if(name != null) {
name = columnMap.get(name);
}
return name;
}
@Override
public String[] generateHeader(T bean) throws CsvRequiredFieldEmptyException {
String[] result = super.generateHeader(bean);
for (int i = 0; i < result.length; i++) {
result[i] = getColumnName1(i);
}
return result;
}
}