我正在使用opencsv 3.6
来从Java bean开始创建一个csv文件。
首先,我尝试了以下代码:
import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import com.opencsv.bean.BeanToCsv;
import com.opencsv.bean.HeaderColumnNameTranslateMappingStrategy;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class CustomBean {
private String name;
private String surname;
public CustomBean(String n, String s) {
this.name = n;
this.surname = s;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getSurname() {
return surname;
}
public static void main(String[] args) {
Map<String,String> mapping = new HashMap<String,String>();
mapping.put("COLUMN1","name");
mapping.put("COLUMN2","surname");
HeaderColumnNameTranslateMappingStrategy<CustomBean> strategy = new HeaderColumnNameTranslateMappingStrategy<CustomBean>();
strategy.setType(CustomBean.class);
strategy.setColumnMapping(mapping);
ArrayList<CustomBean> customUsers = new ArrayList<CustomBean>();
customUsers.add(new CustomBean("Kobe","Bryant"));
BeanToCsv<CustomBean> bean = new BeanToCsv<CustomBean>();
try {
CSVWriter writer = new CSVWriter(new FileWriter("testOut.csv"));
bean.write(strategy, writer, customUsers);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
但是我有以下错误:
Exception in thread "main" java.lang.RuntimeException: Error writing CSV !
at com.opencsv.bean.BeanToCsv.write(BeanToCsv.java:74)
at test.CustomBean.main(CustomBean.java:63)
Caused by: java.lang.NullPointerException
at com.opencsv.bean.HeaderColumnNameTranslateMappingStrategy.getColumnName(HeaderColumnNameTranslateMappingStrategy.java:45)
at com.opencsv.bean.HeaderColumnNameMappingStrategy.findDescriptor(HeaderColumnNameMappingStrategy.java:112)
at com.opencsv.bean.BeanToCsv.processHeader(BeanToCsv.java:103)
at com.opencsv.bean.BeanToCsv.write(BeanToCsv.java:69)
... 1 more
发生这种情况是因为在
getColumnName
类的HeaderColumnNameTranslateMappingStrategy
方法中的opencsv源代码中,存在以下行:return col < header.length ? columnMapping.get(header[col].toUpperCase()) : null;
因此,
header
为null。的确如此,事实上,该类是HeaderColumnNameMappingStrategy
类的子类,其中包含从未初始化的header
变量(String[]
类型)。我在此类中找到的唯一有用的方法是
captureHeader
,但不幸的是,它需要使用CSVReader
作为输入。因此,我创建了一个空的csv文件:
COLUMN1,COLUMN2
我在try/catch块的开头添加了以下几行:
CSVReader reader = new CSVReader(new FileReader("testIn.csv"));
strategy.captureHeader(reader);
这样(我真的不喜欢,因为我必须创建一个csv文件)我也不异常(exception),但是在结果csv文件中,列的名称不遵循映射策略:
"name","surname"
"Kobe","Bryant"
两个问题:
CSVReader
类的方法? 最佳答案
查看BeanToCsv
的源代码,processHeader(...)
方法对提供的 header 不执行任何操作。您唯一的选择是创建一个自定义策略(避免CSVReader
)和一个自定义BeanToCsv
,如下所示
public class CustomBean { ... public static void main(String[] args) { ... HeaderColumnNameTranslateMappingStrategy strategy = new CustomStrategy<CustomBean>(); strategy.setType(CustomBean.class); strategy.setColumnMapping(mapping); ... BeanToCsv bean = new CustomBeanToCsv<CustomBean>(); ... } static class CustomStrategy<T> extends HeaderColumnNameTranslateMappingStrategy { @Override public void setColumnMapping(Map columnMapping) { super.setColumnMapping(columnMapping); header = new String[columnMapping.size()]; int i = 0; for (Map.Entry entry : columnMapping.entrySet()) { header[i] = entry.getKey().toUpperCase(); i++; } } public String[] getHeader() { return header; } } static class CustomBeanToCsv<T> extends BeanToCsv { @Override protected String[] processHeader(MappingStrategy mapper) throws IntrospectionException { if (mapper instanceof CustomStrategy) { return ((CustomStrategy) mapper).getHeader(); } else { return super.processHeader(mapper); } } }}