工作中应该都会遇到解析csv文件的一个问题。
首先说一下如何使用:
解析opencsv很简单,引入相关依赖就可以了就可以。转换成bean的时候
只需要在相应转换bean的类上加入 注解即可。
@CsvBindByName(column = "campaign_name")
private String campaignName;
要注意@CsvBindByName注解只能解析String类型的,如果是其他类型的就需要进行转换了。如
@CsvCustomBindByName(converter = TypeStringConversionLong.class, column = "creative_id")
private Long creativeId;
这是自定义的转换类型,自己可以定义如:
public class TypeStringConversionLong extends AbstractBeanField {
@Override
protected Object convert(String value) throws CsvDataTypeMismatchException, CsvConstraintViolationException {
Field field = getField();
if("charge".equals(field.getName())){
Double v = Double.parseDouble(value);
return Long.parseLong(String.valueOf(v.longValue()*100));
}
return Long.parseLong(value);
}
我们只需要继承AbstractBeanField 重写convert方法就可以了。是不是很简单。
然后再通过输入流读就可以了。
HeaderColumnNameMappingStrategy<KuaiShouAsyncTaskProgramCreativeReportDTO> hs = new HeaderColumnNameMappingStrategy<>();
hs.setType(KuaiShouAsyncTaskProgramCreativeReportDTO.class);
CsvToBean<KuaiShouAsyncTaskProgramCreativeReportDTO> csvToBean = new CsvToBeanBuilder<KuaiShouAsyncTaskProgramCreativeReportDTO>(new InputStreamReader(body, Charset.forName("UTF-8"))).withMappingStrategy(hs).build();
List<KuaiShouAsyncTaskProgramCreativeReportDTO> parse = csvToBean.parse();
但是碰到了找不到第一列值得原因,原本可能是因为大家共同的原因,可能会有bom头导致。在这里
/**
* 读取流中前面的字符,看是否有bom,如果有bom,将bom头先读掉丢弃
*
* @param in
* @return
* @throws IOException
*/
public static InputStream getInputStream(InputStream in) throws IOException {
PushbackInputStream testin = new PushbackInputStream(in);
int ch = testin.read();
if (ch != 0xEF) {
testin.unread(ch);
} else if ((ch = testin.read()) != 0xBB) {
testin.unread(ch);
testin.unread(0xef);
} else if ((ch = testin.read()) != 0xBF) {
throw new IOException("错误的UTF-8格式文件");
}
return testin;
}
代码片
然而也是没用,找了很多办法,也是没啥用,后来索性就升级了一下jar报,问题正常解决。
目前使用的是4.4版本的。4.4版本以下的会出现这种原因。大家可以试一下。