在文件excel文件上传之后,进行单个单元格的值进行处理以及验证。
对单元格的处理如下:
public Object getCellValue(Cell cell) {
Object value = null;
DecimalFormat df = new DecimalFormat("0"); // 格式化为整数
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 日期格式化
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
value = cell.getStringCellValue();
break;
case Cell.CELL_TYPE_NUMERIC:
String dataFormat = cell.getCellStyle().getDataFormatString(); // 单元格格式
boolean isDate = DateUtil.isCellDateFormatted(cell);
if ("General".equals(dataFormat)) {
value = df.format(cell.getNumericCellValue());
} else if (isDate) {
value = sdf.format(cell.getDateCellValue());
} else {
value = cell.getNumericCellValue();
}
break;
case Cell.CELL_TYPE_BOOLEAN:
value = cell.getBooleanCellValue();
break;
case Cell.CELL_TYPE_BLANK:
value = "";
break;
default:
break;
}
return value;
}
可是我在使用的过程中,excel导入的日期格式无法进行判断,因为很多导入excel的人要求设置的是日期格式,而日期格式导入到java后台之后呈现的是一个5、6位数字的形式。
DateUtil提供了一个isCellDateFormatted(Cell cell)的方法进行判断excel该单元格的值是否为日期格式,返回值为布尔类型。
DateUtil.isCellDateFormatted(cell);
通常以上就可以进行判断了,可是我自己在使用的过程中发现判断不准确,一直返回的false。
查看源码之后才发现,原来它里面并没有对汉字进行替换,只是对如下的斜杠以及短横线等进行替换。所以在设置日期格式为2019年1月18日这种格式的时候,工具判断会出现问题。
fs = fs.replaceAll("\\\\-", "-");
fs = fs.replaceAll("\\\\,", ",");
fs = fs.replaceAll("\\\\.", ".");
fs = fs.replaceAll("\\\\ ", " ");
fs = fs.replaceAll(";@", "");
fs = fs.replaceAll("^\\[\\$\\-.*?\\]", "");
fs = fs.replaceAll("^\\[[a-zA-Z]+\\]", "");
解决办法有二:
1、直接修改jar包(修改了之后,对以后项目的迁移以及转换可能有点影响)
2、copy需要的代码,手动创建一个工具类进行判断。
这里贴上我自己修改后的工具类:
public static boolean isCellDateFormatted(Cell cell)
{
if (cell == null) return false;
boolean bDate = false;
double d = cell.getNumericCellValue();
if (isValidExcelDate(d)) {
CellStyle style = cell.getCellStyle();
if (style == null) return false;
int i = style.getDataFormat();
String f = style.getDataFormatString();
bDate = isADateFormat(i, f);
}
return bDate;
}
public static boolean isADateFormat(int formatIndex, String formatString)
{
if (isInternalDateFormat(formatIndex)) {
return true;
}
if ((formatString == null) || (formatString.length() == 0)) {
return false;
}
String fs = formatString;
//下面这一行是自己手动添加的 以支持汉字格式wingzing
fs = fs.replaceAll("[\"|\']","").replaceAll("[年|月|日|时|分|秒|毫秒|微秒]", "");
fs = fs.replaceAll("\\\\-", "-");
fs = fs.replaceAll("\\\\,", ",");
fs = fs.replaceAll("\\\\.", ".");
fs = fs.replaceAll("\\\\ ", " ");
fs = fs.replaceAll(";@", "");
fs = fs.replaceAll("^\\[\\$\\-.*?\\]", "");
fs = fs.replaceAll("^\\[[a-zA-Z]+\\]", "");
return (fs.matches("^[yYmMdDhHsS\\-/,. :]+[ampAMP/]*$"));
}
public static boolean isInternalDateFormat(int format)
{
switch (format) { case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case 45:
case 46:
case 47:
return true;
case 23:
case 24:
case 25:
case 26:
case 27:
case 28:
case 29:
case 30:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
case 38:
case 39:
case 40:
case 41:
case 42:
case 43:
case 44: } return false;
}
public static boolean isValidExcelDate(double value)
{
return (value > -4.940656458412465E-324D);
}
代码都是从源码copy出来后修改的,可以放心使用。
后记
遇到很多工具类不符合自己的预期以及网上人所说,可以尝试阅读一下源码,找一下问题所在,这样才是解决问题以及提升自己能力的最好的选择。