前提:上一篇分享了POI上传解析Excel文件的篇幅,有兴趣的话可以看看
https://blog.csdn.net/xiaozhegaa/article/details/104550793
一、问题描述:开发一个文件上传,解析EXCEL,数据入库的功能
在本地开发时,将CellType类型转化为String,然后读取整个字符串,能正确的得到这个数据,整个流程是没有问题的。
个人使用的是:WPS,非苹果电脑
公司测试的公式:EXCEL、苹果电脑
在EXCEL输入了5.58956, 结果在转化为String时。解析成了5.589969999999999出错
现象配图:
从Excel中,获取数据之前。
明确可以看到:Cell数值为:5.83733。
在本机,打开测试发的EXCEL重新保存后,又不会出现这个问题。这点很重要,有点坑
二、解决过程:DEBUG
结果在转化为String后:
所以,问题是出现在Cell转数据类型的时候有问题。
但是个人电脑开发时,是不会出现这个问题。
分析原因有二:
1、可能是EXCEL的属性问题。本人使用的是WPS,而测试人员使用的是word。更大概率是这种事情
2、苹果电脑和非苹果电脑的问题,这种的可能性比较小。
我电脑也没有word所以没有验证上面的第一种情况,直接出解决方案。
三、上代码
直接用number来解析,扩展getStringValue,改为getStringValue2方法
/**
* 读取Cell内容
* @param cell
* @return
* @author yangziran
*/
private static String getStringValue2(Cell cell) {
String cellValue = "";
if (cell == null) {
return null;
}
int cellType = cell.getCellType();
if (CellType.NUMERIC.getCode() == (cellType)) {
cellValue = realStringValueOfDouble(cell.getNumericCellValue());
} else {
cell.setCellType(CellType.STRING);
cellValue = cell.getStringCellValue();
}
return cellValue;
}
public static String realStringValueOfDouble(Double d) {
String doubleStr = d.toString();
boolean b = doubleStr.contains("E");
int indexOfPoint = doubleStr.indexOf('.');
if (b) {
int indexOfE = doubleStr.indexOf('E');
BigInteger xs = new BigInteger(doubleStr.substring(indexOfPoint + BigInteger.ONE.intValue(), indexOfE));
int pow = Integer.parseInt(doubleStr.substring(indexOfE + BigInteger.ONE.intValue()));
int xsLen = xs.toByteArray().length;
int scale = xsLen - pow > 0 ? xsLen - pow : 0;
final String format = "%." + scale + "f";
doubleStr = String.format(format, d);
} else {
java.util.regex.Pattern p = Pattern.compile(".0$");
java.util.regex.Matcher m = p.matcher(doubleStr);
if (m.find()) {
doubleStr = doubleStr.replace(".0", "");
}
}
return doubleStr;
}
附上DEBUG截图
暂时就这样兼容