Ответ 1
У меня была такая же проблема. Я сделал cell.setCellType(Cell.CELL_TYPE_STRING);
перед чтением строкового значения, которое решило проблему независимо от того, как пользователь отформатировал ячейку.
У меня есть файл excel с таким содержимым:
A1: SomeString
A2: 2
Все поля имеют формат String.
Когда я читаю файл в java с помощью POI, он сообщает, что A2 находится в формате числовых ячеек.
.toString()
.Что я могу сделать, чтобы прочитать значение как строку?
У меня была такая же проблема. Я сделал cell.setCellType(Cell.CELL_TYPE_STRING);
перед чтением строкового значения, которое решило проблему независимо от того, как пользователь отформатировал ячейку.
Я не думаю, что у нас был этот класс, когда вы задавали вопрос, но сегодня есть простой ответ.
Что вы хотите сделать, это использовать класс DataFormatter. Вы передаете эту ячейку, и она делает все возможное, чтобы вернуть вам строку, содержащую то, что Excel покажет вам для этой ячейки. Если вы передадите ему ячейку строки, вы вернете строку. Если вы передадите ему числовую ячейку с применяемыми правилами форматирования, она отформатирует число, основанное на них, и вернет вам строку.
В вашем случае я бы предположил, что числовые ячейки имеют целочисленное правило форматирования, применяемое к ним. Если вы попросите DataFormatter форматировать эти ячейки, он вернет вам строку с цельной строкой в ней.
Также обратите внимание, что многие люди предлагают сделать cell.setCellType(Cell.CELL_TYPE_STRING)
, но Apache POI JavaDocs совершенно ясно заявляют, что вы не должны этого делать! Выполнение вызова setCellType
приведет к отмене форматирования, поскольку javadocs объясняет единственный способ конвертировать в String с оставшимся форматированием - использовать Класс 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 без потери точности.
Как уже упоминалось в Poi JavaDocs (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
Try:
new java.text.DecimalFormat("0").format( cell.getNumericCellValue() )
Правильно отформатировать номер.
Пока ячейка находится в текстовом формате до того, как пользователь вводит число, POI позволит вам получить значение в виде строки. Один из ключей заключается в том, что если в верхнем левом углу ячейки есть маленький зеленый треугольник, который отформатирован как текст, вы сможете получить его значение в виде строки (зеленый треугольник появляется всякий раз, когда появляется что-то вроде числа принуждается в текстовый формат). Если у вас есть форматированные в текстовом формате ячейки, содержащие числа, но POI не позволит вам получать эти значения в виде строк, есть несколько вещей, которые вы можете сделать для данных Таблицы, чтобы это:
Последнее, что вы можете сделать, это то, что если вы используете POI для получения данных из электронной таблицы Excel 2007, вы можете использовать метод getRawValue() класса Cell. Это не волнует формат. Он просто вернет строку с необработанными данными.
Да, это отлично работает
cell.setCellType(Cell.CELL_TYPE_STRING);
даже если у вас возникла проблема с извлечением значения из cell
с формулой, все же это работает.
У нас была та же проблема, и мы вынудили наших пользователей форматировать ячейки как "текст" до, введя значение. Таким образом, Excel правильно сохраняет четные числа в виде текста. Если формат изменяется впоследствии, Excel только изменяет способ отображения значения, но не изменяет способ сохранения значения, если значение не будет введено повторно (например, нажав на возврат в ячейке).
Независимо от того, правильно ли хранит значение Excel в виде текста, маленький зеленый треугольник, который Excel отображает в левом верхнем углу ячейки, если он считает, что ячейка содержит число, но формируется как текст.
Когда мы читаем значение числовой ячейки MS Excel с использованием Apache POI-библиотеки, оно читается как числовое. Но иногда мы хотим, чтобы он читался как строка (например, номера телефонов и т.д.). Вот как я это сделал:
Вставьте новый столбец с первой ячейкой = CONCATENATE ( "!", D2). Я предполагаю, что D2 является идентификатором ячейки вашего столбца номер телефона. Перетащите новую ячейку до конца.
Теперь, если вы прочитаете ячейку с помощью POI, она будет читать формулу вместо расчетного значения. Теперь выполните следующие действия:
Добавить еще один столбец
Выберите полный столбец, созданный на шаге 1. и выберите "Редактировать- > КОПИЯ"
Перейти к верхней ячейке столбца, созданной на шаге 3. и выберите "Редактировать- > Вставить специальные"
В открывшемся окне выберите переключатель "Значения"
Выберите "ОК"
Теперь прочитайте, используя API POI... после чтения в Java... просто удалите первый символ i.e. "!"
У меня также была аналогичная проблема с набором данных из тысяч чисел, и я думаю, что нашел простой способ решения. Мне нужно было ввести апостроф перед номером так, чтобы отдельный DB-импорт всегда видел числа как текст. До этого число 8 будет импортировано как 8.0.
Решение:
Hey Presto все числа, но сохраненные как текст.
Многие из этих ответов относятся к старой документации и классам POI. В новейшей POI 3.16 Ячейка с типами int устарела
Cell.CELL_TYPE_STRING
Вместо этого можно использовать перечисление CellType.
CellType.STRING
Просто не забудьте обновить свой pom с зависимостью poi, а также зависимость poi-ooxml от новой версии 3.16, иначе вы продолжите получать исключения. Одним из преимуществ этой версии является то, что вы можете указать тип ячейки во время создания ячейки, исключая все дополнительные шаги, описанные в предыдущих ответах:
titleRowCell = currentReportRow.createCell(currentReportColumnIndex, CellType.STRING);
отбрасывает int, а затем .toString()
. Это уродливо, но оно работает.
В любом случае вы управляете листом excel? Есть ли шаблон, который пользователи могут предоставить вам? Если это так, вы можете иметь код для ввода входных ячеек для вас.
Похоже, это невозможно сделать в текущей версии POI, основываясь на том, что эта ошибка:
https://issues.apache.org/bugzilla/show_bug.cgi?id=46136
все еще выдающийся.
getStringCellValue возвращает NumberFormatException, если тип ячейки является числовым. Если вы не хотите изменять тип ячейки в строке, вы можете сделать это.
String rsdata = "";
try {
rsdata = cell.getStringValue();
} catch (NumberFormatException ex) {
rsdata = cell.getNumericValue() + "";
}
cell.setCellType(Cell.CELL_TYPE_STRING); отлично работает для меня
Это сработало идеально для меня.
Double legacyRow = row.getCell(col).getNumericCellValue();
String legacyRowStr = legacyRow.toString();
if(legacyRowStr.contains(".0")){
legacyRowStr = legacyRowStr.substring(0, legacyRowStr.length()-2);
}