Npoi ICell.DateCellValue возвращает NullReferenceException

У меня есть столбец Excel:

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

Отформатировано как формат данных даты:

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

И я получаю NullReferenceException, если пытаюсь прочитать значение DateTime.

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

Вы знаете, что здесь не так и как это исправить? Можно ли как-нибудь преобразовать число в DateTime? Например, 31/12/9999 - это 2958465, когда я перехожу в числовой формат.

ICell в расширение строки

public static class NpoiExtension
{
    public static string GetStringValue(this ICell cell)
    {
        switch (cell.CellType)
        {
            case CellType.Numeric:
                if (DateUtil.IsCellDateFormatted(cell)) 
                {
                    try
                    {
                        return cell.DateCellValue.ToString();   
                    }
                    catch (NullReferenceException)
                    {
                        // https://stackoverflow.com/questions/15040567/c-xlsx-date-cell-import-to-datatable-by-npoi-2-0
                        //var prevCulture = Thread.CurrentThread.CurrentCulture;
                        //CultureInfo customCulture = new CultureInfo("en-GB", false);
                        //Thread.CurrentThread.CurrentCulture = customCulture;

                        string dateOutput = cell.DateCellValue.ToString();

                        //Thread.CurrentThread.CurrentCulture = prevCulture;
                        return dateOutput;
                    }
                }
                else
                {
                    return cell.NumericCellValue.ToString();
                }
            case CellType.String:
                return cell.StringCellValue;

            case CellType.Boolean:
                return cell.BooleanCellValue.ToString();

            default:
                return string.Empty;
        }
    }
}

person Muflix    schedule 31.01.2019    source источник
comment
Я попробовал ваш код и получил дату без ошибок. Связана ли ваша проблема с вопросом прокомментировал ваш код? Какая культура у вас есть в Thread.CurrentThread.CurrentCulture?   -  person krlzlx    schedule 01.02.2019
comment
По умолчанию у меня en-GB в Thread.CurrentThread.CurrentCulture. Обычно у меня нет проблем с датами, но у этого столбца есть исключение в DateCellValue. Таким образом, обходным путем было использование DateTime.FromOADate()   -  person Muflix    schedule 01.02.2019
comment
У меня тоже en-GB. Может быть связано с версией NPOI? Какую версию вы используете? Пользуюсь версией 2.4.0.   -  person krlzlx    schedule 01.02.2019
comment
У меня другая версия, DotNetCore.NPOI 1.2.1   -  person Muflix    schedule 01.02.2019
comment
Пробовал успешно с вашей версией NPOI. По-прежнему никаких ошибок.   -  person krlzlx    schedule 01.02.2019
comment
Я не знаю, в чем может быть причина этой ошибки и почему она работает в вашем скрипте.   -  person Muflix    schedule 01.02.2019


Ответы (2)


Я нашел здесь решение Как сделать Я конвертирую серийный номер даты Excel в .NET DateTime? Поэтому я добавляю его в свой сценарий.

public static string GetStringValue(this ICell cell)
{
    switch (cell.CellType)
    {
        case CellType.Numeric:
            if (DateUtil.IsCellDateFormatted(cell)) 
            {
                try
                {
                    return cell.DateCellValue.ToString();
                }
                catch (NullReferenceException)
                {
                    return DateTime.FromOADate(cell.NumericCellValue).ToString();
                }
            }
            return cell.NumericCellValue.ToString();

        case CellType.String:
            return cell.StringCellValue;

        case CellType.Boolean:
            return cell.BooleanCellValue.ToString();

        default:
            return string.Empty;
    }
}
person Muflix    schedule 01.02.2019
comment
Это решение работает как шарм. Странная вещь в моем сценарии заключалась в том, что иногда у меня возникало это исключение NullReferenceException, а в других случаях оно выполнялось совершенно нормально, безумно. Мне кажется, что при первом запуске будет работать нормально, но при втором чтении и т. Д. Это вызовет исключение NullReferenceException без видимой причины. Вот почему некоторые люди говорят, что это нормально, когда на самом деле мы имеем дело с нестабильным поведением, которое невозможно воспроизвести с первого раза. - person Felipe; 04.07.2020

Еще один изящный вариант получения DateTime всякий раз, когда ячейка определена как числовая, - это получение числового значения ячейки:

DateTime.FromOADate(cell.NumericCellValue);

Полный пример:

        private ICell GetCellValue(string position)
        {
            var cr = new CellReference(position);
            var row = m_Sheet.GetRow(cr.Row);
            return row.GetCell(cr.Col);
        }

        public DateTime? GetCellDateValue(string position)
        {
            ICell cellValue = GetCellValue(position);

            if (cellValue == null)
            {
                // Cell doesn't have any value
                return null;
            }

            if (cellValue.CellType == CellType.Numeric)
            {
                return DateTime.FromOADate(cellValue.NumericCellValue);
            }

            return cellValue.DateCellValue;
        }
person Aharon Ohayon    schedule 23.11.2020