之前写了一篇 POI解析Excel--------poi的简单使用及格式转换 的文章,文章中遗留了一个问题
case NUMERIC: // 数字类型 小数,整数,日期
// 如果是数字类型的话,判断是不是日期类型
if (HSSFDateUtil.isCellDateFormatted(cell)) {
// 获取日期类型的单元格的值
Date d = cell.getDateCellValue();
// 进行格式转换
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
cellValue = formatter.format(d);
} else {// 如果不是日期类型的单元格,那么将单元格格式设置成String,然后取值,这里可能会处问题,需要自己多尝试一下
cell.setCellType(CellType.STRING);
cellValue = cell.getStringCellValue();
}
break;
其中HSSFDateUtil.isCellDateFormatted(cell) 不能够判断自定义的日期格式,所以针对Excel中自定义的日期格式会解析错误
自定义的日期格式:
如果按之前的代码,想把这个格式解析成String的话,结果如下:
之前说的可能会出问题,这时候就真的出来了.这不是我们想要的结果
明显,这个自定义的类型直接设置成string类型然后读取是不成功的,我们需要将这个类型加入判断,
short a = cell.getCellStyle().getDataFormat();
System.err.println("单元格格式>>"+a);
通过cell.getCellStyle().getDataFormat()方法 获取数据格式的索引 short 类型 57 ,源码中的注释是:
样式和单元格XF记录中的字段 , 这个真不想深究他了, 反正我们能确定,这个自定义类型的索引是57.
后面就好办了,加一个判断,然后做相应的处理就ok.
public static String getCellStringValue(Cell cell) {
String cellValue = "";
if (cell != null) {
// cell.getCellTypeEnum(),获取单元格类型,case不同类型进行不同处理
switch (cell.getCellTypeEnum()) {
case _NONE: // 未知类型,用于表示初始化前的状态或缺少具体类型。仅供内部使用。
break;
case NUMERIC: // 数字类型 小数,整数,日期
// 如果是数字类型的话,判断是不是日期类型
if (HSSFDateUtil.isCellDateFormatted(cell)) {
Date d = cell.getDateCellValue();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
cellValue = formatter.format(d);
} else if(cell.getCellStyle().getDataFormat() == 57) {
Date d = cell.getDateCellValue();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM");
cellValue = formatter.format(d);
} else {
DecimalFormat df = new DecimalFormat("0");
cellValue = df.format(cell.getNumericCellValue());
}
break;
case STRING: // 字符串类型
cellValue = cell.getStringCellValue();
break;
case FORMULA: // 公式类型
cellValue = String.valueOf(cell.getNumericCellValue());
break;
case BLANK: // 空白的单元格
break;
case BOOLEAN: // 布尔类型
break;
case ERROR: // 错误类型
break;
default:
break;
}
}
return cellValue;
}
第一张图片我们可以看到,对应的自定义格式有很多,通过数据格式索引可以对应的处理其他格式,不清楚有没什么更好的方法,如果有,欢迎留言讨论.后面我如果发现了更好的方法也会及时更新.