2011-02-08 195 views
34

我有噸列的一個巨大的Excel文件,該文件是這樣的: -如何在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的方式。或一種方法來識別提供的值跳過空白單元格?

謝謝。

回答

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

他使用XSSF打開一個XLSX文件(2007+)。 HSSF不會解決他的問題。 – 2011-03-02 20:55:20

9

我一直對這個同樣的問題感到沮喪。這是我用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的錯誤。

+1

進入相同的問題,並使用基於0的索引方法(不通過foreach)和CREAT_NULL_AS_BLANK MissingRowPolicy爲我工作。 – fimez 2012-03-15 20:38:30

+1

優秀。可以確認這在POI 3.8中也適用。 – javatestcase 2012-07-20 21:59:40

51

如果你想獲得所有單元格,不管它們是否存在,那麼迭代器就不適合你。相反,你需要手動取合適的細胞,有可能與缺少格策

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

+0

`row.getCell()`方法已棄用。 – 2011-07-14 07:43:54

+3

它真的不是...... – Gagravarr 2011-07-14 08:30:20

+2

它是`row.getCell(short)`這已棄用。抱歉。 – 2011-07-14 09:33:21

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++; 
    } 
} 
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; 
    } 
} 
1

下面是我工作。 「row.CREATE_NULL_AS_BLANK」似乎不是有效的,但可能缺乏NPOI知識。

HSSFCell dataCell= (HSSFCell)row.GetCell(column, NPOI.SS.UserModel.MissingCellPolicy.CREATE_NULL_AS_BLANK); 
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); 
} 
0
public String[] rowToString(Row row) 
{ 
    Iterator<Cell> cells = row.cellIterator() ; 
    String[] data = new String[row.getLastCellNum()] ; 

    int previousCell = 0 ; 

    Cell cell = cells.next() ; 
    int currentCell = cell.getColumnIndex(); 

    while (true) 
    { 
     if (previousCell == currentCell) { 
      switch (cell.getCellType()) { 
       case Cell.CELL_TYPE_NUMERIC: 
        data[previousCell] = cell.getNumericCellValue()+"" ; 
        break; 
       case Cell.CELL_TYPE_STRING: 
        data[previousCell] = cell.getStringCellValue() ; 
        break; 
        /* // there could be other cases here. 
        case Cell.CELL_TYPE_FORMULA: 
         data[previousCell] =eval.evaluateFormulaCell(cell); 
         break; 
        case Cell.CELL_TYPE_BOOLEAN: 
         data[previousCell] = cell.getBooleanCellValue(); 
         break; 
        case Cell.CELL_TYPE_BLANK: 
         data[previousCell] = ""; 
         break; 
        case Cell.CELL_TYPE_ERROR: 
         data[previousCell] = "ERROR"; 
         break; 
        */ 
      } 
      if(cells.hasNext()){ 
       cell = cells.next() ; 
       currentCell = cell.getColumnIndex(); 
      } else { 
       break ; 
      } 

     } else { 
      data[previousCell] = ""; 
     } 
     previousCell++ ; 

    } 

    return data ; 

} 
相關問題