Apache POI Read xlsx NPE

3
我试图使用问题中的确切代码读取Excel电子表格。一切都正常,但有时在此代码行上的某些单元格会出现NPE:
String value = cell.toString();

为什么会这样?我的工作表中有些单元格怎么会是空的?不可否认,我遇到NPE的单元格并没有包含数据。但并非所有空单元格都会导致NPE。
同样地(如果我在这行代码中加入NPE检查),最终会出现一些明显为空的行:
XSSFRow row = ws.getRow(i);

这些是电子表格中的空行,不包含任何数据。但并非所有的空行都会导致NPE(NullPointerException)。

显然,在这两种情况下进行空值检查可以解决我的直接问题。我只是想知道为什么有时候对象为空。必须有一些逻辑在其中。我只是看不到它。

谢谢。

1个回答

2
并非所有行都需要有一个“Row”对象。想一想,在Excel中新建电子表格时,最多可以有1,048,576行,但保存一个空的电子表格会导致文件大小很小。也就是说,对不存在的行的引用将导致绝对巨大的文件。只有与其相关联的某些内容,如单元格值、格式、边框等,才应存储对行的引用。一行可能看起来是空白的,但可能有一些格式或者曾经有过的内容现在已经消失了。对于行中的“Cell”也有类似的论点。没有理由为未使用的单元格保留“Cell”引用。但是您可以清除“Cell”的内容,而不必删除“Cell”本身;它可以是一个“CELL_TYPE_BLANK”单元格。
如果它从未存在过,则它将是null。即使它没有内容,它可能具有需要表示的格式,因此它不会是null。如果它曾经有内容或格式,除非有人明确删除它(在Excel中右键单击->删除或在POI中使用removeCellremoveRow),否则它不会是null
如果行没有任何内容,那么它可能是null是有意义的。正如您所提到的,您可以在访问之前始终检查getRow返回的Row是否为null,并且您可以在访问之前始终检查getCell返回的Cell是否为null。您还可以向{{link1:getCell}}提供一个Row.MissingCellPolicy来控制该方法的行为。CREATE_NULL_AS_BLANK将为您创建Cell(如果它不存在)。想象一下,对于一个Row,有16,384个Cell,通常只需要其中的几个。
有其他缺失单元格策略。 RETURN_BLANK_AS_NULL 则相反;如果存在但为空,则返回null。默认值RETURN_NULL_AND_BLANK只是返回其中的任何内容,而不采取其他任何操作。

谢谢,这很有道理。由于我无法控制接收到的电子表格,所以在检索行或单元格后,我将进行空值检查。 - TJ Grant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接