使用 OpenCSV,如何使用 MappingStrategy 附加到现有 CSV?我可以找到很多不使用 Bean 映射策略的示例,但我喜欢使用 Bean 策略进行列映射的动态特性,并希望以这种方式工作。这是我的代码,它只是将单行重写为 CSV 文件而不是附加。
我怎样才能解决这个问题?使用 OpenCSV 4.5。注意:我将 FileWriter 设置为append=true。这种情况并没有按照我的预期进行。重新运行此方法只会导致用标题和单行覆盖整个文件。
public void addRowToCSV(PerfMetric rowData) {
File file = new File(PerfTestMetric.CSV_FILE_PATH);
try {
CSVWriter writer = new CSVWriter(new FileWriter(file, true));
CustomCSVMappingStrategy<PerfMetric> mappingStrategy
= new CustomCSVMappingStrategy<>();
mappingStrategy.setType(PerfMetric.class);
StatefulBeanToCsv<PerfMetric> beanToCsv
= new StatefulBeanToCsvBuilder<PerfMetric>(writer)
.withMappingStrategy(mappingStrategy)
.withSeparator(',')
.withApplyQuotesToAll(false)
.build();
try {
beanToCsv.write(rowData);
} catch (CsvDataTypeMismatchException e) {
e.printStackTrace();
} catch (CsvRequiredFieldEmptyException e) {
e.printStackTrace();
}
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
或者,通常的模式是将所有行加载到列表中,然后重写整个文件?我能够通过编写两个 MappingStrategy 映射策略,然后有条件地将它们与 if-file-exists 一起使用来使其工作,但这样做会在我的代码中留下“未经检查的分配”警告。不理想;希望有一个优雅的解决方案?
我已将 OpenCSV 更新到版本 5.1 并开始工作。就我而言,我需要 CSV 标头具有特定的名称和位置,因此我同时使用 @CsvBindByName 和 @CsvBindByPosition,并且需要创建一个自定义 MappingStrategy 才能使其正常工作。
后来,我需要编辑 MappingStrategy 以启用附加功能,因此当它处于附加模式时,我不需要生成 CSV 标头。
public class CustomMappingStrategy<T> extends ColumnPositionMappingStrategy<T> {
private boolean useHeader=true;
public CustomMappingStrategy(){
}
public CustomMappingStrategy(boolean useHeader) {
this.useHeader = useHeader;
}
@Override
public String[] generateHeader(T bean) throws CsvRequiredFieldEmptyException {
final int numColumns = FieldUtils.getAllFields(bean.getClass()).length;
super.setColumnMapping(new String[numColumns]);
if (numColumns == -1) {
return super.generateHeader(bean);
}
String[] header = new String[numColumns];
if(!useHeader){
return ArrayUtils.EMPTY_STRING_ARRAY;
}
BeanField<T, Integer> beanField;
for (int i = 0; i < numColumns; i++){
beanField = findField(i);
String columnHeaderName = extractHeaderName(beanField);
header[i] = columnHeaderName;
}
return header;
}
private String extractHeaderName(final BeanField<T, Integer> beanField){
if (beanField == null || beanField.getField() == null || beanField.getField().getDeclaredAnnotationsByType(CsvBindByName.class).length == 0){
return StringUtils.EMPTY;
}
//return value of CsvBindByName annotation
final CsvBindByName bindByNameAnnotation = beanField.getField().getDeclaredAnnotationsByType(CsvBindByName.class)[0];
return bindByNameAnnotation.column();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您使用默认构造函数,它会将标头添加到生成的 CSV 中,并且使用布尔值,您可以告诉它添加标头或忽略它。
| 归档时间: |
|
| 查看次数: |
2903 次 |
| 最近记录: |