我使用OpenCSV将Java bean写入CSV文件。下面是代码片段:
public void generateCSVFile(List<?> domains, String[] columns, String fileName) {
try {
final FileWriter writer = new FileWriter(fileName);
CSVWriter csvWriter = new CSVWriter(writer);
csvWriter.writeNext(columns);
if (CollectionUtils.isNotEmpty(domains)) {
ColumnPositionMappingStrategy mappingStrategy = new ColumnPositionMappingStrategy();
mappingStrategy.setType(Class.forName(domains.get(0).getClass().getTypeName()));
mappingStrategy.setColumnMapping(columns);
StatefulBeanToCsvBuilder<?> builder = new StatefulBeanToCsvBuilder(
csvWriter);
StatefulBeanToCsv beanWriter = builder.withMappingStrategy(mappingStrategy).build();
beanWriter.write(domains);
csvWriter.close();
writer.close();
}
}
catch(Exception e){
LOG.error("Exception occured while generating CSV file : {}", e)
}
}
这在opensv 4.1版本中可以正常工作。这样就生成了一个CSV文件,文件的标题和列是按照我传递列(String[])的顺序生成的。最近,我将版本更新到5.7.1,之后它生成的CSV文件只有头,而不是数据。它生成一个空文件,在生成的文件中只有头文件。
我试过使用HeaderColumnNameMappingStrategy
。它生成带有数据的文件,但是按照属性的升序生成,并且使用大写的属性,因为这是默认行为。
是否有一种方法可以让ColumnPositionMappingStrategy
在5.7.1版本中工作,就像它在4.1版本中工作一样?
此方法适用于OpenCSV版本4.1和5.7:
序列化public static <T> void writeToCSV(String location, Class<T> type, List<T> records, String[] columns)
throws IOException, CsvRequiredFieldEmptyException, CsvDataTypeMismatchException {
ColumnPositionMappingStrategy<T> mappingStrategy = new ColumnPositionMappingStrategy<>();
mappingStrategy.setType(type);
mappingStrategy.setColumnMapping(columns);
try (Writer writer = new FileWriter(location)) {
StatefulBeanToCsv<T> beanToCsv = new StatefulBeanToCsvBuilder<T>(writer)
.withMappingStrategy(mappingStrategy)
.withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
.build();
beanToCsv.write(records);
}
}
用法示例String[] columns = new String[]{"a", "b"};
List<Bean> objects = List.of(new Bean("A1", "B1"),
new Bean("A2", "B2"));
String location = "beans.csv";
try {
CSVUtils.writeToCSV(location, Bean.class, objects, columns);
} catch (IOException | CsvRequiredFieldEmptyException | CsvDataTypeMismatchException e) {
e.printStackTrace();
}
已知类Bean
有两个String属性a
和b
。
我在Java 8、11和17上测试了上面的代码。