Excel提取2位精度数值时小数位数异常问题求助
Excel数值提取精度问题解决方案
问题根源
Excel中显示的两位小数数值,底层实际以double类型存储,而double存在浮点精度误差。你原代码中先将double转成字符串再转BigDecimal,会把误差带入最终结果,导致出现2248.399999996这类异常值。
解决方法
方法1:按Excel显示格式提取字符串(推荐)
使用POI的DataFormatter类,直接获取单元格格式化后的显示字符串,再转BigDecimal,完全匹配Excel界面显示的数值:
import org.apache.poi.ss.usermodel.DataFormatter; // 在处理NUMERIC类型单元格时替换原有逻辑 if (cell.getCellType() == CellType.NUMERIC) { DataFormatter formatter = new DataFormatter(); String formattedValue = formatter.formatCellValue(cell); BigDecimal numericCellValue = new BigDecimal(formattedValue); object.put(classMapping.get(index), numericCellValue); continue; }
DataFormatter会自动识别单元格设置的小数位数格式,返回和Excel界面一致的字符串,避免浮点误差问题。
方法2:强制保留两位小数并四舍五入
如果确定所有数值都是两位小数精度,可以对double值进行四舍五入处理后转BigDecimal:
import java.math.BigDecimal; import java.math.RoundingMode; // 在处理NUMERIC类型单元格时替换原有逻辑 if (cell.getCellType() == CellType.NUMERIC) { double numericCellValueAsDouble = cell.getNumericCellValue(); BigDecimal numericCellValue = new BigDecimal(numericCellValueAsDouble) .setScale(2, RoundingMode.HALF_UP); object.put(classMapping.get(index), numericCellValue); continue; }
setScale(2, RoundingMode.HALF_UP)会将数值四舍五入到两位小数,消除浮点误差带来的多余小数位。
原代码问题说明
你原代码中new BigDecimal(String.valueOf(numericCellValueAsDouble))的逻辑存在缺陷:因为double本身的浮点误差,String.valueOf(double)会输出带误差的字符串(比如2248.399999996),转成BigDecimal后自然保留了这些错误位数。
内容的提问来源于stack exchange,提问作者Salanta Rares
相关产品推荐
相关产品推荐

