Чтение целого числа из числовой ячейки с использованием Apache POI в java

У меня есть приложение, которое читает лист xls с помощью apache poi. Когда ячейка имеет числовое значение, я читаю ее с помощью row.getCell(i).getNumericValue(). Но он возвращает цифру с плавающей запятой. например, если значение ячейки равно 1, оно возвращает 1,0. Могу ли я преобразовать его в int? Любая помощь приветствуется. Я пробовал Integer.parseInt(значение) - но он выдает исключение NumberFormat. Любая помощь приветствуется. Вот псевдокод:

FileInputStream file = new FileInputStream(new File("C:\\test.xls"));
HSSFWorkbook workbook = new HSSFWorkbook(file);
HSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
while(rowIterator.hasNext()) {
    Row row = rowIterator.next();
    Iterator<Cell> cellIterator = row.cellIterator();
    while(cellIterator.hasNext()) {
        Cell cell = cellIterator.next();
        switch(cell.getCellType()) {
            case Cell.CELL_TYPE_NUMERIC:
                String value= String.valueOf(cell.getNumericCellValue());
                int intVal = Integer.parseInt(value)-->>throws Exception

person Parameswar    schedule 10.09.2014    source источник
comment
Понятно, извлеките значение как двойное, как conert к int :Double val = cell.getNumericCellValue(); val.intValue даст ответ   -  person Parameswar    schedule 10.09.2014
comment
Вот простое решение: double dval = row.getCell(cellCounter, XSSFRow.CREATE_NULL_AS_BLANK ).getNumericCellValue(); System.out.println(new Integer(new Double(dval).intValue()).toString());   -  person Mike Preston    schedule 19.08.2016


Ответы (7)


Вы можете прочитать значение int как строку apache poi, используя простые шаги

Сначала подсчитайте строки в листах, используя метод ниже

private  int getRowCount(Sheet currentSheet) {
        int rowCount = 0;
        Iterator<Row> rowIterator = currentSheet.iterator();

        while(rowIterator.hasNext()) {  
            Row row = rowIterator.next();

            if(row == null || row.getCell(0) == null || row.getCell(0).getStringCellValue().trim().equals("") || row.getCell(0).toString().trim().equals("") 
                    || row.getCell(0).getCellType()==Cell.CELL_TYPE_BLANK){
                break;
            }
            else
                rowCount=rowCount + 1;
        }       
        return rowCount;
    }

Затем используйте приведенный ниже код в своем методе

    Workbook workbook = WorkbookFactory.create(new File("c:/test.xls");
    Sheet marksSheet = (Sheet) workbook.getSheet("Sheet1");
            int zoneLastCount = 0;
            if(marksSheet !=null ) {
                zoneLastCount = getRowCount(marksSheet);
            }
    int zone = zoneLastCount-1;
    int column=1

    for(int i = 0; i < zone; i++) {         
        Row currentrow = marksSheet.getRow(i);
        double year = Double.parseDouble(currentrow.getCell(columnno).toString());
        int year1 = (int)year;
        String str = String.valueOf(year1);
    }
person VISHWANATH N P    schedule 05.08.2016
comment
Этот код не будет работать для числовых ячеек, так как вы пытаетесь прочитать строковое значение, не проверяя/убедившись, что ваши ячейки являются числовыми. - person Gagravarr; 05.08.2016
comment
теперь он работает, общее значение вашей ячейки также работает, нет необходимости проверять - person VISHWANATH N P; 06.08.2016

Числа в Excel (за исключением нескольких крайних случаев) хранятся как числа с плавающей запятой. Числа с плавающей запятой в Java, отформатированные как строка, печатаются с завершающей десятичной точкой, как вы видите.

Предполагая, что вы действительно хотели "дать мне строку, похожую на то, что Excel показывает для этой ячейки", тогда не вызывайте cell.toString(). Это не даст вам то, что вы хотите в большинстве случаев

Вместо этого вам нужно использовать класс DataFormatter, который предоставляет методы, прочитать правила формата Excel, примененные к ячейке, а затем воссоздать (насколько это возможно) правила в Java

Ваш код должен быть:

Workbook wb = WorkbookFactory.create(new File("c:/test.xls");
DataFormatter fmt = new DataFormatter();
Sheet sheet = wb.getSheetAt(0);
for (Row row : sheet) {
     Cell cell = row.getcell(0, Row.RETURN_BLANK_AS_NULL);
     if(cell!=null) {
          String value = fmt.formatCellValue(cell);
          if (! value.trim().isEmpty()) {
             System.out.println("Cell as string is " + value);
          }
     }
 }

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

person Gagravarr    schedule 10.09.2014
comment
Очень чистый подход. Спасибо. - person gschambial; 06.09.2017

Кому-то может пригодиться этот лайфхак:

cell.setCellType(CellType.STRING);
int value = Integer.parseInt(cell.getStringCellValue());

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

person no id    schedule 24.05.2017
comment
setCellType устарело в новых версиях. - person Pranjal Choladhara; 31.01.2021

  // to extract the exact numerical value either integer/double
  DataFormatter fmt = new DataFormatter();
  Iterator<Cell> cellIterator = row.cellIterator();
  while (cellIterator.hasNext()) {
    Cell cell = cellIterator.next();
    switch (cell.getCellType()) {
      case NUMERIC:
        if (DateUtil.isCellDateFormatted(cell)) {
          Date date = cell.getDateCellValue();
          DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
          //DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
          fetchedRow.add(dateFormat.format(date));
        } else {
          fetchedRow.add(fmt.formatCellValue(cell));
        }
        rowEmpty = false;
        break;
      case STRING:
        fetchedRow.add(cell.toString());
        rowEmpty = false;
        break;
      case BOOLEAN:
        fetchedRow.add(cell.toString());
        rowEmpty = false;
        break;
      case FORMULA:
        fetchedRow.add(Double.toString(cell.getNumericCellValue()));
        rowEmpty = false;
        break;
      case BLANK:
        fetchedRow.add("");
        break;
    }
  }
  if (!rowEmpty) {
    allRows.add(fetchedRow.toArray(new String[0]));
    count++;
  }
  if (count >= limit) {
    break;
  }
}
return allRows;

}

eaxmple для чтения ограниченного количества строк и использования DataFormatter для получения точного числового значения либо целого числа, либо двойного значения. Это сработает.

person Mallikharjuna    schedule 14.10.2019

Вы можете просто ввести преобразование float в int, например:

String value = String.valueOf((int)cell.getNumericCellValue());
person Sani Shrestha    schedule 24.08.2017

Попробуйте сделать следующее (чтобы получить длинный):

long value = (long) currentCell.getNumericValue();
person Mohamed Maalej    schedule 04.02.2019

Ниже реализация работала для меня:

private Object getValue(Cell cell) {
    switch (cell.getCellType()) {
        case Cell.CELL_TYPE_STRING:
            return cell.getStringCellValue();
        case Cell.CELL_TYPE_NUMERIC:
            return String.valueOf((int) cell.getNumericCellValue());
        case Cell.CELL_TYPE_BOOLEAN:
            return cell.getBooleanCellValue();
        case Cell.CELL_TYPE_ERROR:
            return cell.getErrorCellValue();
        case Cell.CELL_TYPE_FORMULA:
            return cell.getCellFormula();
        case Cell.CELL_TYPE_BLANK:
            return null;
    }
    return null;
}
person M T    schedule 20.04.2020