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

StackOverflow https://stackoverflow.com/questions/1072561

  •  21-08-2019
  •  | 
  •  

Вопрос

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

    • А1:SomeString

    • А2:2

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

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

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

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

Это было полезно?

Решение

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

Другие советы

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

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

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

Также обратите внимание, что многие люди предлагают сделать cell.setCellType(Cell.CELL_TYPE_STRING), но В JavaDocs Apache POI совершенно четко указано, что этого делать не следует.!Выполнение 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

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

рекомендуемые:

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

старый:

cell.setCellType(Cell.CELL_TYPE_STRING);

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

Пытаться:

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

Необходимо правильно отформатировать номер.

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

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

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

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

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

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

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

  4. Выберите полный столбец, созданный на шаге 1.и выберите «Правка-> КОПИРОВАТЬ».

  5. Перейдите к верхней ячейке столбца, созданного на шаге 3.и выберите «Правка» -> «Специальная вставка».

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

  7. Выберите «ОК».

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

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

Решение:

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

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

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

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

Я бы предпочел пойти по пути ответа Уилла или Винаяка Дорналы, к сожалению, они сильно повлияли на мою игру.я пошел за ХАККИ решение неявного приведения:

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

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

Сноска:NumericColumn - это int, который генерируется из чтения заголовка обработанного файла.

public class Excellib {
public String getExceldata(String sheetname,int rownum,int cellnum, boolean isString) {
    String retVal=null;
    try {
        FileInputStream fis=new FileInputStream("E:\\Sample-Automation-Workspace\\SampleTestDataDriven\\Registration.xlsx");
        Workbook wb=WorkbookFactory.create(fis);
        Sheet s=wb.getSheet(sheetname);
        Row r=s.getRow(rownum);
        Cell c=r.getCell(cellnum);
        if(c.getCellType() == Cell.CELL_TYPE_STRING)
        retVal=c.getStringCellValue();
        else {
            retVal = String.valueOf(c.getNumericCellValue());
        }

Я попробовал это, и это сработало для меня

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

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

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

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

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

все еще остается выдающимся.

cell.setCellType(Cell.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);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top