Как читать числовые строки в ячейках Excel в виде строки (а не числа)?

  • У меня есть файл excel с таким содержимым:

    • A1: SomeString

    • A2: 2

    Все поля имеют формат String.

  • Когда я читаю файл в java с помощью POI, он сообщает, что A2 находится в формате числовых ячеек.

  • Проблема в том, что значение в A2 может быть 2 или 2,0 (и я хочу, чтобы их можно было отличить), поэтому я не могу просто использовать .toString().

Что я могу сделать, чтобы прочитать значение как строку?

Ответ 1

У меня была такая же проблема. Я сделал cell.setCellType(Cell.CELL_TYPE_STRING); перед чтением строкового значения, которое решило проблему независимо от того, как пользователь отформатировал ячейку.

Ответ 2

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

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

В вашем случае я бы предположил, что числовые ячейки имеют целочисленное правило форматирования, применяемое к ним. Если вы попросите DataFormatter форматировать эти ячейки, он вернет вам строку с цельной строкой в ​​ней.

Также обратите внимание, что многие люди предлагают сделать cell.setCellType(Cell.CELL_TYPE_STRING), но Apache POI JavaDocs совершенно ясно заявляют, что вы не должны этого делать! Выполнение вызова setCellType приведет к отмене форматирования, поскольку javadocs объясняет единственный способ конвертировать в String с оставшимся форматированием - использовать Класс DataFormatter.

Ответ 3

Следующий код работал у меня для любого типа ячейки.

InputStream inp =getClass().getResourceAsStream("filename.xls"));
Workbook wb = WorkbookFactory.create(inp);
DataFormatter objDefaultFormat = new DataFormatter();
FormulaEvaluator objFormulaEvaluator = new HSSFFormulaEvaluator((HSSFWorkbook) wb);

Sheet sheet= wb.getSheetAt(0);
Iterator<Row> objIterator = sheet.rowIterator();

while(objIterator.hasNext()){

    Row row = objIterator.next();
    Cell cellValue = row.getCell(0);
    objFormulaEvaluator.evaluate(cellValue); // This will evaluate the cell, And any type of cell will return string value
    String cellValueStr = objDefaultFormat.formatCellValue(cellValue,objFormulaEvaluator);

}

Ответ 4

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

if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
    String str = NumberToTextConverter.toText(cell.getNumericCellValue())
}

NumberToTextConverter может корректно преобразовывать двойное значение в текст с помощью правил Excel без потери точности.

Ответ 6

Try:

new java.text.DecimalFormat("0").format( cell.getNumericCellValue() )

Правильно отформатировать номер.

Ответ 7

Пока ячейка находится в текстовом формате до того, как пользователь вводит число, POI позволит вам получить значение в виде строки. Один из ключей заключается в том, что если в верхнем левом углу ячейки есть маленький зеленый треугольник, который отформатирован как текст, вы сможете получить его значение в виде строки (зеленый треугольник появляется всякий раз, когда появляется что-то вроде числа принуждается в текстовый формат). Если у вас есть форматированные в текстовом формате ячейки, содержащие числа, но POI не позволит вам получать эти значения в виде строк, есть несколько вещей, которые вы можете сделать для данных Таблицы, чтобы это:

  • Дважды щелкните по ячейке, чтобы курсор редактирования находился внутри ячейки, затем нажмите "Enter" (который может выполняться только по одной ячейке за раз).
  • Используйте функцию преобразования текста Excel 2007 (которая может быть выполнена сразу для нескольких ячеек).
  • Вырезать оскорбительные значения в другое место, переформатировать ячейки электронных таблиц в виде текста, а затем отменить ранее вырезанные значения как неформатированные значения обратно в правильную область.

Последнее, что вы можете сделать, это то, что если вы используете POI для получения данных из электронной таблицы Excel 2007, вы можете использовать метод getRawValue() класса Cell. Это не волнует формат. Он просто вернет строку с необработанными данными.

Ответ 8

Да, это отлично работает

cell.setCellType(Cell.CELL_TYPE_STRING);

даже если у вас возникла проблема с извлечением значения из cell с формулой, все же это работает.

Ответ 9

У нас была та же проблема, и мы вынудили наших пользователей форматировать ячейки как "текст" до, введя значение. Таким образом, Excel правильно сохраняет четные числа в виде текста. Если формат изменяется впоследствии, Excel только изменяет способ отображения значения, но не изменяет способ сохранения значения, если значение не будет введено повторно (например, нажав на возврат в ячейке).

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

Ответ 10

Когда мы читаем значение числовой ячейки MS Excel с использованием Apache POI-библиотеки, оно читается как числовое. Но иногда мы хотим, чтобы он читался как строка (например, номера телефонов и т.д.). Вот как я это сделал:

  • Вставьте новый столбец с первой ячейкой = CONCATENATE ( "!", D2). Я предполагаю, что D2 является идентификатором ячейки вашего столбца номер телефона. Перетащите новую ячейку до конца.

  • Теперь, если вы прочитаете ячейку с помощью POI, она будет читать формулу вместо расчетного значения. Теперь выполните следующие действия:

  • Добавить еще один столбец

  • Выберите полный столбец, созданный на шаге 1. и выберите "Редактировать- > КОПИЯ"

  • Перейти к верхней ячейке столбца, созданной на шаге 3. и выберите "Редактировать- > Вставить специальные"

  • В открывшемся окне выберите переключатель "Значения"

  • Выберите "ОК"

  • Теперь прочитайте, используя API POI... после чтения в Java... просто удалите первый символ i.e. "!"

Ответ 11

У меня также была аналогичная проблема с набором данных из тысяч чисел, и я думаю, что нашел простой способ решения. Мне нужно было ввести апостроф перед номером так, чтобы отдельный DB-импорт всегда видел числа как текст. До этого число 8 будет импортировано как 8.0.

Решение:

  • Сохраните все форматирование как Общие.
  • Здесь я предполагаю, что числа хранятся в столбце A, начиная с строки 1.
  • Поместите "в столбце B" и скопируйте столько строк, сколько необходимо. На листе ничего не отображается, но, щелкнув по ячейке, вы можете увидеть апостоф в панели формул.
  • В столбце C: = B1 & A1.
  • Выберите все ячейки в столбце C и сделайте специальную вставку в столбце D с помощью параметра Значения.

Hey Presto все числа, но сохраненные как текст.

Ответ 12

Многие из этих ответов относятся к старой документации и классам POI. В новейшей POI 3.16 Ячейка с типами int устарела

Cell.CELL_TYPE_STRING

введите описание изображения здесь

Вместо этого можно использовать перечисление CellType.

CellType.STRING 

Просто не забудьте обновить свой pom с зависимостью poi, а также зависимость poi-ooxml от новой версии 3.16, иначе вы продолжите получать исключения. Одним из преимуществ этой версии является то, что вы можете указать тип ячейки во время создания ячейки, исключая все дополнительные шаги, описанные в предыдущих ответах:

titleRowCell = currentReportRow.createCell(currentReportColumnIndex, CellType.STRING);

Ответ 13

отбрасывает int, а затем .toString(). Это уродливо, но оно работает.

Ответ 14

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

Ответ 16

getStringCellValue возвращает NumberFormatException, если тип ячейки является числовым. Если вы не хотите изменять тип ячейки в строке, вы можете сделать это.

String rsdata = "";
try {
    rsdata = cell.getStringValue();
} catch (NumberFormatException ex) {
    rsdata = cell.getNumericValue() + "";
}

Ответ 17

cell.setCellType(Cell.CELL_TYPE_STRING); отлично работает для меня

Ответ 18

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

Double legacyRow = row.getCell(col).getNumericCellValue();
String legacyRowStr = legacyRow.toString();
if(legacyRowStr.contains(".0")){
    legacyRowStr = legacyRowStr.substring(0, legacyRowStr.length()-2);
}