Как я могу читать числовые строки в ячейках Excel как строку (а не цифры)?

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

    • A1: SomeString

    • A2: 2

    все поля имеют строковый формат.

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

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

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

19 ответов


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


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

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

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

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


ниже код работал для меня для любого типа клеток.

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

}

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

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

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


Как уже упоминалось в JavaDocs Poi(https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Cell.html#setCellType%28int%29) Не используйте:

cell.setCellType(Cell.CELL_TYPE_STRING);

но использовать:

DataFormatter df = new DataFormatter();
String value = df.formatCellValue(cell);

больше примеров на http://massapi.com/class/da/DataFormatter.html


попробуй:

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

должен правильно форматировать число.


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

рекомендуется:

        DataFormatter dataFormatter = new DataFormatter();
        String value = dataFormatter.formatCellValue(cell);

старый:

cell.setCellType(Cell.CELL_TYPE_STRING);

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


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

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

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


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

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

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

  3. добавить еще один столбец

  4. выберите полный столбец, созданный на шаге 1. и выберите Edit - >COPY

  5. перейти к верхней ячейке столбца, созданного на Шаге 3. и выберите Edit - >Paste Special

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

  7. выберите "OK"

  8. теперь читайте с помощью POI API ... после чтения на Java ... просто удалите первый характер, т. е. "!"


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

устранение:

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

Эй Presto все номера, но хранятся в виде текста.


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

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

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

Cell.CELL_TYPE_STRING

enter image description here

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

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

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

HACKY решение неявное приведение:

for (Row row : sheet){
String strValue = (row.getCell(numericColumn)+""); // hack
...

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

сноску: numericColumn Является int, который генерируется из чтения заголовка обрабатываемого файла.


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

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


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


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

https://issues.apache.org/bugzilla/show_bug.cgi?id=46136

по-прежнему нерешенным.


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


приведите к int, затем сделайте .toString(). Это некрасиво, но это работает.


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

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