Java 如何在ApachePOI中获取Excel空白单元格值?

Java 如何在ApachePOI中获取Excel空白单元格值?,java,apache,apache-poi,Java,Apache,Apache Poi,我有一个巨大的excel文件,其中包含大量列,如下所示:- Column1 Column2 Column3 Column4 Column5 abc def ghi mno pqr ...... 这是我为打印这些值而编写的代码: try { FileInputStream inputStr = new FileInputStream(fileName); XSSFWorkbook xssfWo

我有一个巨大的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。还是一种识别显示的值跳过空白单元格的方法

谢谢。

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

对于(int i=0;i我对同样的问题感到沮丧。以下是我对poi-3.7-20101029和poi-3.8的发现

RowIterator和CellIterator不支持对空单元格或行进行迭代—只支持物理定义的单元格(可以为空)

返回我所期望的结果的解决方案需要使用基于0的
Row.getCell([int],Row.CREATE\u NULL\u AS\u BLANK)
,就像Chavira的答案所暗示的那样(假设为8个单元格行)。或者,您可以在迭代时使用
cell.columnIndex
值来检查跳转数字


恼人的是,在使用方法1创建空白单元格之后,迭代器将返回现在创建的空白单元格。我认为Cyter迭代器忽略了MissingCellPolicy是一个错误。

< P>如果你想得到所有单元格,不管它们是否存在,那么迭代器不适合你。相反,你需要手动获取合适的单元格,比如一个丢失的单元策略

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.MissingCellPolicy.CREATE_NULL_AS_BLANK);
       // Print the cell for debugging
       System.out.println("CELL: " + cn + " --> " + cell.toString());
   }
}
for(行:页){

对于(int cn=0;cn来说,原因很简单: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++;
    }
}
//假设您有一个二维数组。
字符串[][]值=…;//已分配
POIFSFileSystem fileSystem=新的POIFSFileSystem(新文件输入流(文件名));
HSSF工作簿=新的HSSF工作簿(文件系统);
//检查每一张工作表。
对于(int sheetPos=0;sheetPos
这对我很有效

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

下面是对我有效的方法。“row.CREATE\u NULL\u AS\u BLANK”似乎无效,但可能是缺少NPOI知识

HSSFCell dataCell= (HSSFCell)row.GetCell(column, NPOI.SS.UserModel.MissingCellPolicy.CREATE_NULL_AS_BLANK);
List cellDataList=newarraylist();
int lineNumber=0;
while(roweiterator.hasNext()){
HSSFRow HSSFRow=(HSSFRow)行迭代器.next();
//System.out.println(“在If之前”);
lineNumber++;
如果(行号==1){continue;}
//System.out.println(“out-side if”);
迭代器迭代器=hssfRow.cellIterator();
List celltemplast=newarraylist();
int current=0,next=1;
while(iterator.hasNext()){
单元格hssfCell=iterator.next();
当前=hssfCell.getColumnIndex();
if(当前
公共字符串[]行字符串(行)
{
迭代器单元格=行。单元格迭代器();
字符串[]数据=新字符串[row.getLastCellNum()];
int-previousCell=0;
Cell=cells.next();
int currentCell=cell.getColumnIndex();
while(true)
{
if(previousCell==currentCell){
开关(cell.getCellType()){
case Cell.Cell\u类型\u数值:
数据[previousCell]=cell.getNumericCellValue()+“”;
打破
case Cell.Cell\u类型\u字符串:
数据[previousCell]=cell.getStringCellValue();
打破
/*//这里可能还有其他情况。
case Cell.Cell_类型_公式:
数据[previousCell]=评估公式单元格(单元格);
打破
case Cell.Cell\u类型\u布尔值:
数据[previousCell]=cell.getBooleanCellValue();
打破
case Cell.Cell\u类型\u空白:
数据[previousCell]=“”;
打破
case Cell.Cell\u类型\u错误:
数据[previousCell]=“错误”;
打破
*/
}
if(cells.hasNext()){
cell=cells.next();
currentCell=cell.getColumnIndex();
}否则{
打破
}
}否则{
数据[previousCell]=“”;
}
previousCell++;
}
返回数据;
}

他正在使用XSSF打开一个XLSX文件(2007+)。HSSF无法解决他的问题。
row.getCell()
方法已弃用。它是
row.getCell(short)
已弃用。抱歉,它是
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);
}
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 ;

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