Как получить значение пустой ячейки Excel в Apache POI? - PullRequest
36 голосов
/ 08 февраля 2011

У меня есть огромный файл 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, есть ли способв котором я могу получить эти значения как ноль.или способ распознать, что в представленных значениях пропущены пустые ячейки?

Спасибо.

Ответы [ 8 ]

57 голосов
/ 13 июля 2011

Если вы хотите получить все ячейки, независимо от того, существуют они или нет, тогда итератор не для вас. Вместо этого вам нужно вручную выбрать соответствующие ячейки, вероятно, с отсутствующей политикой ячеек

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

Подробнее об этом можно узнать в документации Apache POI по итерации по ячейкам

10 голосов
/ 09 марта 2011

Я был разочарован этой же проблемой.Вот что я нашел с poi-3.7-20101029 и poi-3.8.

RowIterator и CellIterator не поддерживают итерацию по пустым ячейкам или строкам - только физически определенные ячейки (которые могут быть пустыми).

Решение, которое возвращает то, что я ожидаю, требует использования Row.getCell([int], Row.CREATE_NULL_AS_BLANK), основанного на 0, во многом аналогично тому, на который ссылается ответ Чавиры (предполагая 8 рядов ячеек).Или вы можете использовать значение Cell.columnIndex во время итерации, чтобы проверять наличие числа ...

Раздражающе, после создания пустых ячеек с использованием метода # 1, итераторы вернут теперь созданные ячейки BLANK.Я считаю ошибкой то, что MissingCellPolicy игнорируется CellIterator.

3 голосов
/ 14 июля 2011

Причина довольно проста: файлы 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++;
    }
}
2 голосов
/ 12 апреля 2012

Вот что у меня сработало.«Row.CREATE_NULL_AS_BLANK», по-видимому, недействителен, но это может быть недостатком знаний NPOI.

HSSFCell dataCell= (HSSFCell)row.GetCell(column, NPOI.SS.UserModel.MissingCellPolicy.CREATE_NULL_AS_BLANK);
1 голос
/ 01 марта 2011
        for(org.apache.poi.ss.usermodel.Row tmp : hssfSheet){
            for(int i = 0; i<8;i++){
                System.out.println(tmp.getCell(i));
            }               
        }
0 голосов
/ 25 июня 2015
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 ;

}
0 голосов
/ 13 июня 2012
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 голосов
/ 13 октября 2011

Это сработало для меня ....

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