Java新手:如何处理DataFormatter返回的Object数字并存入数组
常见认知误区修正
首先先纠正三个你当前代码里的认知偏差和实现问题:
DataFormatter.formatCellValue()方法的实际返回值是String类型,并非你以为的Object类型。它的核心作用是将POI读取到的单元格内容(数字、日期、公式等)按照Excel内配置的格式规则,转换为和你打开Excel时看到的完全一致的展示文本,不会直接返回原始数值对象。- 你原代码中调用
formatCellValue后没有接收返回值,就算拿到了格式化结果也没有做存储,这也是你无法把结果存入数组的直接原因。 - 你当前的循环逻辑存在资源浪费问题:每次循环都新建一个
DataFormatter实例,这个类本身可复用,重复实例化没有必要。
具体实现思路
根据你“把指定列的读取结果存入数组”的需求,结合原代码的读取范围(从第1行到第300行,共300条数据),可以按照下面的逻辑调整:
- 将
DataFormatter的实例化逻辑挪到循环外部,复用同一个格式化器 - 提前根据已知的读取条数(300条)初始化对应长度的数组,减少动态扩容的开销
- 增加空值判断,避免因为空行、空单元格抛出空指针异常
参考代码
场景1:需要保存格式化后的展示文本
也就是直接使用DataFormatter输出的内容存入数组的场景:
// 循环外初始化格式化器,复用实例 DataFormatter formatter = new DataFormatter(); // 提前初始化长度为300的字符串数组,对应300条读取结果 String[] resultArray = new String[300]; int close = 0; while (close < 300) { // 对应原代码的行索引偏移,从第1行(0基)开始读取 int currentRowIndex = close + 1; Row currentRow = sheet.getRow(currentRowIndex); // 空行直接存入空字符串 if (currentRow == null) { resultArray[close] = ""; close++; continue; } Cell targetCell = currentRow.getCell(4); // 空单元格直接存入空字符串 if (targetCell == null) { resultArray[close] = ""; close++; continue; } // 格式化结果直接存入数组对应位置 resultArray[close] = formatter.formatCellValue(targetCell); close++; }
场景2:需要保存原始数值而非格式化文本
如果你实际想要存储的是单元格里的数字本身(而非带千分位、小数格式的展示文本),不需要用DataFormatter,可以直接读取单元格的数值内容存入数值数组:
// 初始化长度为300的浮点型数组,Excel内数字默认以浮点格式存储 double[] numericArray = new double[300]; int close = 0; while (close < 300) { int currentRowIndex = close + 1; Row currentRow = sheet.getRow(currentRowIndex); if (currentRow == null) { numericArray[close] = 0; close++; continue; } Cell targetCell = currentRow.getCell(4); if (targetCell == null) { numericArray[close] = 0; close++; continue; } // 直接读取单元格的数值内容存入数组 numericArray[close] = targetCell.getNumericCellValue(); close++; }
额外注意事项
- 如果目标列存在公式单元格,使用
DataFormatter时需要传入FormulaEvaluator实例,否则会拿到公式本身的字符串而非计算结果,调用方式为formatter.formatCellValue(targetCell, formulaEvaluator)。 - 如果后续需要动态调整存储的数量,不需要固定长度数组的话,可以先用
List<String>或者List<Double>存储结果,最后通过list.toArray()方法转换为数组即可。
内容的提问来源于stack exchange,提问作者theJavaNoob
相关产品推荐
相关产品推荐

