使用 Apache POI 访问单元格时出现 NullPointerException

NullPointerException when accessing a cell with Apache POI

我正在尝试使用 Apache POI 读取 Excel 文件。 我的目标是从每一行中获取单元格 2 和 3 并将它们放入一个数组中。在某些行中,单元格编号 3 是空的(我不是在谈论 EMPTY、NULL 或 BLANK)。如果您在 Excel 中检查它们,则为空。

其中一些空单元格(并非全部)导致 NullPonterException:线程 "main" java.lang.NullPointerException 中的异常。它发生在尝试获取单元格值或单元格类型时。我的印象是那个位置没有牢房。

同时,如果我对该特定行执行 row.createCell(2).setCellType(1);,程序将继续执行,直到下一个此类单元格。这是继续从下一行读取单元格的唯一解决方法(我能找到)。

您能否帮助我了解如何识别这些单元格(使用代码)并将我的解决方法落实到位,以便我可以继续阅读直到文件结尾?

这是代码:

static ArrayList<String> getFirstFile() throws IOException
{
    FileInputStream fileIn = null;

    ArrayList <String> namesFirstFile = new ArrayList <String>();
    String folderPath = "C:\";
    String indivList1 = "filename.xls";

    fileIn = new FileInputStream(folderPath+indivList1);
    POIFSFileSystem fs = new POIFSFileSystem(fileIn);
    HSSFWorkbook wb = new HSSFWorkbook(fs);
    HSSFSheet sheet = wb.getSheetAt(0);
    int rowNumber = 6; //skipping the first 6 rows as irrelevant
    HSSFRow row = sheet.getRow(rowNumber);
    String firstName = "";
    String lastName = "";

    while(row.getCell(0).getCellType() == 0) {
        lastName = row.getCell(1).toString();
        firstName = row.getCell(2).toString();

        namesFirstFile.add((rowNumber-6), (lastName + " " + firstName));
        rowNumber++;
        row = sheet.getRow(rowNumber);          
    }
}

您必须检查该单元格是否存在。请记住,如果存在一行并不意味着所有单元格都存在。如果该特定单元格不存在,则执行 get 操作会抛出空指针错误,但创建单元格不会抛出错误,因为它会在该特定行中创建该单元格。仅当该单元格对象存在时,您才可以对该单元格对象执行点运算符。

例如:

如果第 3 个位置的单元格存在,这将起作用:

row1.getCell(2).getStringCellValue(); // if the value is of string type

否则您已使用 if 检查并在需要时创建该单元格。

// This checks if the cell is present or it'll return null if the cell
// is not present (it won't check the value in cell)
if (row1.getCell(2) != null)
{
   row1.createCell(2);
}

如果该单元格不存在并且您唯一的 objective 是获取该值,您可以在数组中设置一个默认值。

这两行行不通,因为它将单元格对象转换为字符串,而不是它的内容:

lastName = row.getCell(1).toString();
firstName = row.getCell(2).toString();

您必须将其更改为:

lastName = row.getCell(1).getStringCellValue();
firstName = row.getCell(2).getStringCellValue();

如果您在该单元格中没有任何值,则无需执行此操作:

if (row.getCell(2) != null)
{
    row.createCell(2);
}
firstName = row.getCell(2).toString();

将其更改为:

if (row.getCell(2) != null)
{
    firstName = row.getCell(2); // your other operations
} else {
    firstname = "default value"; // your other operations
}

创建单元格而未设置值时,无需获取单元格值。

只有在为单元格设置值时才必须使用 row.createCell(2);。在这里你没有价值。

尝试设置 Row.MissingCellPolicy:

  • static Row.MissingCellPolicy CREATE_NULL_AS_BLANK

    A new, blank cell is created for missing cells.

  • static Row.MissingCellPolicy RETURN_BLANK_AS_NULL

    Missing cells are returned as null, as are blank cells

  • static Row.MissingCellPolicy RETURN_NULL_AND_BLANK

    Missing cells are returned as null, Blank cells are returned as normal

This question 对该主题进行了很好的讨论。