错误:如何读取Excel中的空单元格

4

我正在尝试使用POI读取Excel中的数据。如何检查是否为空单元格?

我不知道缺少了什么,我认为这应该是有效的:

java.util.Iterator<Row> rows = worksheet.rowIterator();

HSSFRow row = (HSSFRow) rows.next();
HSSFCell cellF1 = (HSSFCell) row.getCell(5);
if(cellF1.getCellType() == HSSFCell.CELL_TYPE_BLANK) {
  String val = "";
}

在if语句中我遇到了错误(空指针),但只有使用这个方法我才能检查到:

   while (rows.hasNext()) {
    HSSFRow row = (HSSFRow) rows.next();
    java.util.Iterator<Cell> cells = row.cellIterator();
    while (cells.hasNext()) {
      HSSFCell cell = (HSSFCell) cells.next();
      if(cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) {
        String emptytype = "";
        System.out.println("empty");
      }
    }
  }

如果你得到了一个空指针,那意味着cellF1未定义。 你确定第六个单元格已经定义了吗?记住,单元格是从0开始计数的。 - Derk
5个回答

9

这是Row.getCell单参数版本的正常行为。如果您查看API文档,它明确说明getCell在未定义单元格时会返回null。许多java函数表现出这种行为,因此编码时考虑到这一点是没有问题的。因此,您的代码可能如下:

boolean hasDataFlag = true;    
HSSFRow row = sheet.getRow(rowNumber);
hasDataFlag = (row != null);
HSSFCell cell = null;
if (hasDataFlag) cell = row.getCell(cellNumber);
hasDataFlag = (cell != null);
if (hasDataFlag) hasDataFlag = (cell.getCellType() != Cell.CELL_TYPE_BLANK);
if (hasDataFlag) {
    // process the cell here
}

另外,您可以使用另一版本的Row.getCell,该版本需要第二个参数来指定缺失单元格策略。这个版本允许您指定getCell对于空单元格返回一个空单元格。因此,以下是一些备选代码:

HSSFRow row = sheet.getRow(rowNumber);
if (row != null) {
    HSSFCell cell = row.getCell(cellNumber, Row.RETURN_BLANK_AS_NULL);
    if (cell != null) {
        // process cell here
    }
}

或者,如果您愿意,您可以将策略指定为Row.CREATE_NULL_AS_BLANK。在这种情况下,您将用if (cell.getCellType()!= Cell.CELL_TYPE_BLANK)替换if (cell!= null)


如果(hasDataFlag),则获取单元格的值并将其赋给cell变量。然后,检查cell是否为空,并将结果存储在hasDataFlag变量中。如果hasDataFlag为true,则检查单元格类型是否不是空白单元格,并将结果存储在hasDataFlag变量中。最后,如果hasDataFlag为true,则执行以下操作: - rifo pangemanan
不客气。再详细解释一下,只有当单元格中有数据时,hasDataFlag 才会被设置为 true。因此,它只有在以下情况下才为 true:a)如果行不为空;b)如果单元格不为空;c)如果单元格类型不是 CELL_TYPE_BLANK。我之所以这样编码,是因为它避免了大量嵌套的 if 语句。我本可以使用嵌套的 if 语句(就像我在第二个示例中所做的那样),但我个人认为使用 hasDataFlag 可以得到更清晰的代码。但这只是我的个人风格;你觉得哪种方式更容易就用哪种方式。 - Howard Schutzman

5
如果您使用CellIterator,则只会获取已经定义过的单元格(没有null单元格,但是会有blank单元格)。如果您想获取所有单元格,请按索引获取。 按索引获取单元格,可以像这样操作:
 Sheet sheet = workbook.getSheetAt(0);
 for (int rowNumber = sheet.getFirstRowNum(); rowNumber <= sheet.getLastRowNum(); rowNumber++) {
    Row row = sheet.getRow(rowNumber);
    if (row == null) {
         // This row is completely empty
    } else {
         // The row has data
         for (int cellNumber = row.getFirstCellNum(); cellNumber <= row.getLastCellNum(); cellNumber++) {
             Cell cell = row.getCell(cellNumber);
             if (cell == null || cell.getCellType() == Cell.CELL_TYPE_BLANK) {
                 // This cell is empty
             } else {
                 // This cell has data in it
             }
         }
    }
 }

这很棒。你定义了起始行、结束行、起始单元格和结束单元格。 在我的代码中,我只是循环包含数据的单元格和行。 对我来说,POI API如何区分空单元格和空白单元格仍然是个谜,无论如何非常感谢。 - rifo pangemanan

2
Cell cell = row.getCell(x, Row.CREATE_NULL_AS_BLANK);

这个技巧对我非常有帮助。看看它是否对你有用...


0

public String getCellData(String File_Name, int Sheet_Num, int Row_Num, int Col_Num) throws IOException {

    FileInputStream fileIn = new FileInputStream(System.getProperty("user.dir")+"\\"+File_Name+".xlsx");
    XSSFWorkbook workbook = new XSSFWorkbook(fileIn);
    XSSFSheet sheet=workbook.getSheetAt(Sheet_Num-1);
    XSSFRow row = sheet.getRow(Row_Num-1);
    XSSFCell cell= row.getCell(Col_Num-1);
    String celldata;
    if(cell!=null){
    celldata= cell.getStringCellValue();
    }
    else 
        celldata ="";
    fileIn.close();
    return celldata;

    }

0
int column, rownumber = 0; // just for showing the example code

Row row = sheet1.getRow(rownumber); // just for showing the example code

if (row!= null)
    mycell = row.getCell(0);
if (mycell != null && mycell.getCellType() != Cell.CELL_TYPE_BLANK) {
    System.out.println(mycell.getStringCellValue());
}
else{
    System.out.println("whatever");  
}

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