如何在Apache POI中获取Excel空白单元格值?

时间:2011-02-08 04:45:23

标签: java apache apache-poi

我有一个包含大量列的巨大excel文件,如下所示: -

Column1 Column2 Column3 Column4 Column5
abc             def             ghi
        mno             pqr
......

这是我编写的用于打印这些值的代码:

try {
    FileInputStream inputStr = new FileInputStream(fileName);
    XSSFWorkbook xssfWork = new XSSFWorkbook(inputStr) ;
    XSSFSheet sheet1 = xssfWork.getSheetAt(0);
    Iterator rowItr = sheet1.rowIterator();

    while ( rowItr.hasNext() ) {
        XSSFRow row = (XSSFRow) rowItr.next();
        System.out.println("ROW:-->");
        Iterator cellItr = row.cellIterator();

        while ( cellItr.hasNext() ) {
            XSSFCell cell = (XSSFCell) cellItr.next();
            System.out.println("CELL:-->"+cell.toString());
        }
    }
} catch (Exception e) {
    e.printStackTrace();
}

此代码生成的输出为: -

ROW:-->
CELL:-->Column1
CELL:-->Column2
CELL:-->Column3
CELL:-->Column4
CELL:-->Column5
ROW:-->
CELL:-->abc
CELL:-->def
CELL:-->ghi
ROW:-->
CELL:-->mno
CELL:-->pqr

所以,如果我们看一下上面的输出,我们可以注意到我留下空白值的单元格没有被POI库拾取,有没有办法可以将这些值作为null。或者一种方法来识别所呈现的值跳过空白单元格?

感谢。

9 个答案:

答案 0 :(得分:56)

如果你想得到所有细胞,无论它们是否存在,那么迭代器不适合你。相反,您需要手动获取相应的单元格,可能是缺少单元格策略

for(Row row : sheet) {
   for(int cn=0; cn<row.getLastCellNum(); cn++) {
       // If the cell is missing from the file, generate a blank one
       // (Works by specifying a MissingCellPolicy)
       Cell cell = row.getCell(cn, Row.CREATE_NULL_AS_BLANK);
       // Print the cell for debugging
       System.out.println("CELL: " + cn + " --> " + cell.toString());
   }
}

the Apache POI documentation on iterating over cells

中有关于所有这些内容的详细信息

答案 1 :(得分:10)

我对同样的问题感到沮丧。这是我在poi-3.7-20101029和poi-3.8中找到的。

RowIterator和CellIterator不支持迭代NULL单元格或行 - 只有物理定义的单元格(可以是BLANK)。

返回我期望的解决方案需要使用基于0的Row.getCell([int], Row.CREATE_NULL_AS_BLANK),就像Chavira的答案暗示(假设8个单元格行)。或者,您可以在迭代时使用Cell.columnIndex值来检查跳数......

令人讨厌的是,在使用方法#1创建空白单元格之后,迭代器将返回现在创建的BLANK单元格。我认为这是一个错误,CellIterator会忽略MissingCellPolicy。

答案 2 :(得分:3)

原因很简单:Excel文件可以包含尽可能多的行和尽可能多的列,因此返回所有可用的空白行和列将使单元格变得庞大且占用大量内存。

假设你有10x10的表,在Excel中,它不是“完全”10x10,因为你可以很容易地用空白单元格添加11x10,那么POI应该返回第11列吗?

执行您要求的操作的一种方法是使用HSSFCell.getColumnIndex()

示例:

//Assuming your have a 2 dimensional array.
String[][] values = ......;// It is assigned

POIFSFileSystem fileSystem = new POIFSFileSystem(new FileInputStream(fileName));
HSSFWorkbook workbook = new HSSFWorkbook(fileSystem);

//Going through every worksheet.
for (int sheetPos = 0; sheetPos < workbook.getNumberOfSheets(); sheetPos++) {
    HSSFSheet sheet = workbook.getSheetAt(sheetPos);

    int rowPos = 0;
    Iterator<Row> rows = sheet.rowIterator();
    while (rows.hasNext()) {
        HSSFRow row = (HSSFRow) rows.next();

        Iterator<Cell> cells = row.cellIterator();
        while (cells.hasNext()) {
            HSSFCell cell = (HSSFCell) cells.next();
            String value = "";

            switch (cell.getCellType()) {
                case HSSFCell.CELL_TYPE_NUMERIC:
                    value = BigDecimal.valueOf(cell.getNumericCellValue()).toPlainString();
                    break;

                case HSSFCell.CELL_TYPE_STRING:
                    value = cell.getStringCellValue();
                    break;

                case HSSFCell.CELL_TYPE_BLANK:
                    value = "";
                    break;

                case HSSFCell.CELL_TYPE_FORMULA:
                    value = cell.getCellFormula();
                    break;

                default:
                    break;
            }

            values[rowPos][cell.getColumnIndex()] = value;
        }

        rowPos++;
    }
}

答案 3 :(得分:1)

        for(org.apache.poi.ss.usermodel.Row tmp : hssfSheet){
            for(int i = 0; i<8;i++){
                System.out.println(tmp.getCell(i));
            }               
        }

答案 4 :(得分:1)

以下是对我有用的。 “row.CREATE_NULL_AS_BLANK”似乎没有效果,但可能缺乏NPOI知识。

HSSFCell dataCell= (HSSFCell)row.GetCell(column, NPOI.SS.UserModel.MissingCellPolicy.CREATE_NULL_AS_BLANK);

答案 5 :(得分:0)

这对我有用....

int rowNumber;
int previousCell;
int currentCell;
int currentRowNumber;
HSSFCell cell;

while (rows.hasNext()) {
    previousCell = -1;
    currentCell = 0;
    while (cellIterator.hasNext()) {
        cell = (HSSFCell) cellIterator.next();
        currentCell = cell.getColumnIndex();
        if (previousCell == currentCell-1)  {
            //...
        }
        else {
            System.out.println("Blank cell found");
        }
        previousCell = currentCell;
    }
}

答案 6 :(得分:0)

List cellDataList = new ArrayList(); 

int lineNumber = 0;   

while (rowIterator.hasNext()) {
    HSSFRow hssfRow = (HSSFRow) rowIterator.next();
    //System.out.println("Befor If");
    lineNumber++;
    if(lineNumber==1){continue;}
    //System.out.println("Out side if ");

    Iterator<Cell> iterator = hssfRow.cellIterator();
    List<Cell> cellTempList = new ArrayList();
    int current = 0, next = 1;
    while (iterator.hasNext()) {
      Cell hssfCell = iterator.next();
      current = hssfCell.getColumnIndex();

      if(current<next){
          System.out.println("Condition Satisfied");
      }
      else{
          int loop = current-next;
          System.out.println("inside else Loop value : "+(loop));
          for(int k=0;k<loop+1;k++){
             System.out.println("Adding nulls");
             cellTempList.add(null);
             next = next + 1;
          }
      }

      cellTempList.add(hssfCell);

      next = next + 1;
      System.out.println("At End  next value is : "+next);
  }
  cellDataList.add(cellTempList);
}

答案 7 :(得分:0)

min

答案 8 :(得分:0)

for (Row row: sheet){
// This will return null if cell is empty / blank
Cell cell = row.getCell(columnNumber);
}