Ошибка локали даты POI в Apache с использованием формулы = now ()

Итак, я пытался прочитать файл excel, используя POI, используя java, все было хорошо, пока не появилась дата. Файл excel - это шаблон, который я не могу изменить, а для даты в нем используется формула = сейчас ().

Когда я смотрю в формате ячейки, языковой стандарт установлен на Английский Индия. Это, например, нарушает преобразование времени. 16-03-2018 становится 2015-11-17Проверь это.

Единственное решение, которое я нашел методом проб и ошибок, было то, что код работает, только если я изменю локаль на Английский США.

Загрузите файл Excel

А вот как это выглядит в моей системе (Locale India).

Фрагмент

    case Cell.CELL_TYPE_FORMULA:

                    SimpleDateFormat DtFormat = new SimpleDateFormat("yyyy-MM-dd");
                    Date date = cell.getDateCellValue();
                    System.out.println(DtFormat.format(date));
                    break;

Полный код Java

public static void main(String[] args) throws IOException
{
    String excelFilePath = "C:\\Users\\oi309\\Documents\\Projects\\AOI\\AOI Standard Format1.xlsx";
    FileInputStream inputStream = new FileInputStream(new File(excelFilePath));

    Workbook workbook = null;

    if (excelFilePath.endsWith("xlsx"))
    {
        workbook = new XSSFWorkbook(inputStream);
    }
    else if (excelFilePath.endsWith("xls"))
    {
        workbook = new HSSFWorkbook(inputStream);
    }
    else
    {
        throw new IllegalArgumentException("The specified file is not Excel file");
    }

    Sheet firstSheet = workbook.getSheetAt(0);
    Iterator<Row> iterator = firstSheet.iterator();

    while (iterator.hasNext())
    {
        Row nextRow = iterator.next();
        Iterator<Cell> cellIterator = nextRow.cellIterator();

        while (cellIterator.hasNext())
        {
            Cell cell = cellIterator.next();

            if (cell.getCellType() != Cell.CELL_TYPE_BLANK)
            {

                switch (cell.getCellType())
                {

                case Cell.CELL_TYPE_STRING:
                    if (!cell.getStringCellValue().contains("NVS"))

                        System.out.print(cell.getStringCellValue());
                    break;
                case Cell.CELL_TYPE_FORMULA:

                    SimpleDateFormat DtFormat = new SimpleDateFormat("yyyy-MM-dd");
                    Date date = cell.getDateCellValue();
                    System.out.println(DtFormat.format(date));
                    break;
                case Cell.CELL_TYPE_NUMERIC:

                    System.out.print(cell.getNumericCellValue());
                    break;

                }

            }
        }
        System.out.println();

    }

    workbook.close();
    inputStream.close();
}

Заранее спасибо.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
413
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема, с которой вы столкнулись, не имеет ничего общего с форматом ячейки или локалью. Значение ячейки, хранящееся в файле вместе с формулой =NOW():

<c r = "B4" s = "5"><f ca = "1">NOW()</f><v>42325.30892476852</v></c>

и это 17 ноября 2015 г. (ровно 17 ноября 2015 г., 07:24:51). Это значение даты, которое apache poi прочитает из файла без переоценки формулы.

И если вы посмотрите на свойства документа (/docProps/core.xml), вы обнаружите:

<dcterms:modified xsi:type = "dcterms:W3CDTF">2015-11-17T13:25:31Z</dcterms:modified>

Итак, 2015-11-17 была датой, когда этот файл был в последний раз открыт в Excel и пересчитан. На данный момент дата =NOW() - 17 ноября 2015 года.

Поэтому я подозреваю, что этот файл является шаблоном, созданным 2015-11-17, а затем заполненным значениями вне Excel и без пересчета. Если вы открываете этот файл в Excel, =NOW() будет пересчитан, так как это непостоянная функция. И тогда дата будет текущей датой. Если вы затем повторно сохраните файл без дальнейших изменений, то значение ячейки, сохраненное в файле вместе с формулой =NOW(), также будет текущим значением даты и времени. После этого apache poi прочтет эту дату.

Поэтому для чтения этого файла с помощью apache poi без предварительного открытия и повторного сохранения в Excel требуется переоценка формулы. Самый простой способ:

...
    workbook.getCreationHelper().createFormulaEvaluator().evaluateAll();

    Sheet firstSheet = workbook.getSheetAt(0);
    Iterator<Row> iterator = firstSheet.iterator();

    while (iterator.hasNext())
...

Пожалуйста, прочтите Формула оценки о других возможностях оценки формул с помощью apache poi.

Спасибо, Аксель, AssessmentAll () работает. Возможно, проблема в самом файле Excel.

Tuhin Bagh 16.03.2018 11:22

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