【问题标题】:Issue reading in a cell from Excel with Apache POI使用 Apache POI 从 Excel 中读取单元格时出现问题
【发布时间】:2018-07-11 05:45:03
【问题描述】:

我正在尝试使用 Apache POI 读取旧的(2007 年之前和 XLS)Excel 文件。我的程序走到行的末尾并向上迭代,直到找到既不是空也不是空的东西。然后它会重复几次并抓取这些单元格。这个程序可以很好地阅读在 Office 2010 中制作的 XLSX 和 XLS 文件。

我收到以下错误消息:

Exception in thread "main" java.lang.NumberFormatException: empty String
    at sun.misc.FloatingDecimal.readJavaFormatString(Unknown Source)
    at java.lang.Double.parseDouble(Unknown Source)

在线:

num = Double.parseDouble(str);

来自代码:

str = cell.toString();

if (str != "" || str != null) {
    System.out.println("Cell is a string");
    num = Double.parseDouble(str);
} else {
    System.out.println("Cell is numeric.");
    num = cell.getNumericCellValue();
}

cell 是文档中最后一个不为空或不为空的单元格。当我尝试打印第一个不为空或 null 的单元格时,它什么也不打印,所以我认为我没有正确访问它。

【问题讨论】:

  • 为什么不使用单元格类型来识别它是字符串还是数字还是空?
  • 我试过了,当我这样做时它会返回一个答案,当我将它视为返回的答案时,单元格仍显示为“空白”。我打开了它的引用的 excel 文件,数字是正确的,它试图读取的单元格不是空白的。
  • 你确定你不是一个人吗? Excel 从 A1 开始,POI 从第 0 行第 0 列开始。(POI 具有将 excel 引用转换为行/列以避免此类错误的实用方法)
  • 我实际上是通过将它踩了几个空格来检查这个想法。数据从第 54 行或类似的地方开始,一直运行到第 10 行,我将其回滚到 40 行,但它仍然在每个行上都返回“”。

标签: java excel apache-poi


【解决方案1】:

也许您在空白单元格中阅读的原因是由于使用了 Apache POI 的正确子组件来读取 Excel 文件。对 XLS 格式使用 HSSF(Horrible SpreadSheet Format),对 XLSX 格式使用 XSSF(XML SpreadSheet Format)。


至于代码本身,您可能需要优化您的布尔表达式。您现在的方式,因为您使用的是 or 运算符 (||),

  • if 语句的第一部分将执行 if str != null,并且
  • if 语句的 else 部分将在 if str == null 时执行。

如果不能将str 解析为数字,则if 语句的第一部分将在调用Double.parseDouble 时抛出NumberFormatException

也许下面的代码 sn-p 会对你有所帮助:

if (str == null || str.trim().isEmpty()) {
    // handle null and empty strings
} else if (cell.getType() == Cell.CELL_TYPE_NUMERIC) {
    System.out.println("Cell is numeric.");
    num = cell.getNumericCellValue();
} else {
    // If the cell is not numeric, Double.parseDouble(str) 
    // will most likely throw a NumberFormatException
}

要了解有关Cell 的更多信息,请阅读其Javadoc

【讨论】:

  • 异常 NumberFormatException 是提示,所以我给你投了赞成票。
  • 在更灵活的情况下,您的代码会对我有所帮助,但问题是我不知道为什么它们被读取为 null 或空,而且我不知道如何处理它们。他们不应该读为 null 或空,我看过表格,并且单元格中的数据正式是字符串,一遍又一遍类似于“0.205”。
  • @Nick,这段代码有效:double num = Double.parseDouble("0.205");试试看!
  • 哦,检查格式或单元格类型。确保它是字符串或浮点数,而不是来自公式。这就是上面的代码检查 CELL_TYPE_NUMERIC 的原因。但是单元格类型也可以是字符串,这应该不是问题。你现在明白了吗?
  • @TheOriginalAndroid 代码有效,但问题是正在解析的字符串是空白的,即使我从一个我确定不是空的单元格发送数据。
【解决方案2】:

最好评估细胞类型,然后做你需要的。我使用这段代码来处理单元格数据(检查我是否处理了空白单元格):

switch (cell.getCellType()) {
    case Cell.CELL_TYPE_STRING:
        str = cell.toString().trim();
        break;
    case Cell.CELL_TYPE_NUMERIC:
        if (DateUtil.isCellDateFormatted(cell)) {
            //you should change this to your application date format
            objSimpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");
            str = objSimpleDateFormat.format(cell.getDateCellValue());
        } else {
            num = cell.getNumericCellValue();
            str = String.valueOf(cell.getNumericCellValue());
        }
        break;
    case Cell.CELL_TYPE_BLANK:
        str = "";
        break;
    case Cell.CELL_TYPE_ERROR:
        str = "";
        break;
    case Cell.CELL_TYPE_BOOLEAN:
        str = String.valueOf(cell.getBooleanCellValue());
    break;
}

【讨论】:

  • @luigi 感谢您的回复。我很快就会对此进行测试。
  • @Nick,告诉我上面的代码是否适合你。如果是这样,那么我不会提供更完整的示例代码。基本上,我认为这段代码应该可以工作。
【解决方案3】:

如果我们都知道是什么代码行号导致了异常,那就太好了。

我怀疑你的第一行代码是原因。对象单元格可以为空,空地址不能转换为字符串类型。您可以通过代码检查。

注意:该代码可以在 Office 2010 中使用很好,但我认为此类问题可能发生在任何 Excel 版本中。

【讨论】:

  • 我刚刚更新了主帖以反映发现错误的位置。虽然错误并不能反映整个问题。为什么我的单元格确实不是空白的却被读取为空白?
猜你喜欢
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-22
  • 1970-01-01
  • 2020-12-16
  • 1970-01-01
  • 2015-03-19
相关资源
最近更新 更多