Чтение даты из xlsx с использованием open xml sdk

У меня свидание в формате4/5/2011" (месяц / день / год) в файле xlsx в одной из ячеек. Я пытаюсь разобрать файл и загрузить эти данные в некоторых классах.

Пока часть, где я анализирую ячейку, выглядит так:

string cellValue = cell.InnerText;
if (cell.DataType != null)
{
    switch (cell.DataType.Value)
    {
        case CellValues.SharedString:
            // get string from shared string table
            cellValue = this.GetStringFromSharedStringTable(int.Parse(cellValue));
            break;
    }
}

Я надеялся, что эта дата станет ячейкой. Тип данных. Правда при разборе клетки с датой "4/5/2011", значение cell.DataType равно нулю, а значение ячейки равно "40638" и это не индекс таблицы общих строк. (Я пробовал это раньше, и это закончилось исключением.)

Есть идеи? Спасибо

Ответы на вопрос(4)

StyleIndex для чисел 2 и для даты 3

Дата это в ODate, и вы можете преобразовать в строковый формат

value = DateTime.FromOADate (double.Parse (value)). ToShortDateString ();

 Butsaty03 авг. 2018 г., 16:58
У меня есть поле даты с StyleIndex = 11

поэтому я знаю, что данная ячейка должна быть DateTime. Таким образом, я заканчиваю в этом методе строковым параметром excelDateTime, содержащим значение ячейки, которое обычно будет числом OADate вроде "+42540,041666666664" .

public static bool TryParseExcelDateTime(string excelDateTimeAsString, out DateTime dateTime)
{
    double oaDateAsDouble;
    if (!double.TryParse(excelDateTimeAsString, out oaDateAsDouble)) //this line is Culture dependent!
        return false;
    //[...]
    dateTime = DateTime.FromOADate(oaDateAsDouble);

Моя проблема в том, что конечный пользователь находится в Германии, и, поскольку это веб-сайт, мыустановите для Thread.CurrentThread.CurrentCulture и Thread.CurrentThread.CurrentUICulture значение "DE-де», И когда вы звонитеdouble.TryParse, он использует культуру для разбора числа. Итак, эта строка:double.TryParse("42540.041666666664", out oaDate) действительно работает, но возвращается42540041666666664 как и в Германии, точка - это разделитель групп.DateTime.FromOADate затем происходит сбой, потому что число выходит за пределы диапазона (minOaDate = -657435.0, maxOaDate = +2958465.99999999).

Это заставляет меня думать, что:

независимо от локали пользователяВ этом случае документ OpenXML содержит числа, отформатированные в локали по умолчанию (в любом случае US «инвариант» с точкой в качестве десятичного разделителя). Я'искал, но не нашел спецификацию для этого.при выполненииdouble.TryParse на потенциальной строке OADate, мы должны сделать это сdouble.TryParse(excelDateTimeAsString, NumberStyles.Any, CultureInfo.InvariantCulture, out oaDateAsDouble)), Я'я использую CultureInfo.InvariantCulture, но это должен быть любой пункт 1, который я неТочно знаю.
 Marc K17 мар. 2017 г., 17:00
У меня была точно такая же проблема. Я решил это с этим:Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

http://epplus.codeplex.com/

Обратите внимание, что у него есть лицензия LGPL. Поэтому, если вам нужно, чтобы ваша база кода была защищена от проблем GPL, просто используйте библиотеку как есть, и ваша оригинальная лицензия на базу кода безопасна.

 CKmum01 нояб. 2012 г., 14:03
Нет. На самом деле вы должны получить часть стилевого документа. Затем найдите ячейкуформатирование записи. Это будет иметь numberformat = "1" или такие цифры. 14-18 относятся к формату даты. Вы'Затем придется искать формат даты, а затем загрузить данныеstackoverflow.com/questions/8929799/...
 Santhos01 нояб. 2012 г., 13:58
Я не понимаю Я ожидаю, что числовой формат что-то вродечисло: #.###" или же "дата: м / д / г, То число, которое я получил из клетки, должно что-то значить. Вы знаете, что это значит?
 Santhos22 нояб. 2013 г., 17:19
Я недавно попробовал эту библиотеку, и она действительно очень проста в использовании и для некоторых решений, вероятно, намного лучше, чем оригинальная открытая XML-SDK
 Santhos01 нояб. 2012 г., 13:27
Я бы предпочел открыть xml sdk, но если я не найду решение, я попробую это. Спасибо
 CKmum01 нояб. 2012 г., 13:35
у вас есть решение в openxml sdk, но оно слишком запутанное, чтобы сделать это в нескольких утверждениях. Вот's указатель - часть документа style сообщает вам формат числа. итерировать в них, выбрать соответствующий элемент
Решение Вопроса

пропуская неправильный 29 февраля 1900 года как действительный день. Вы должны быть в состоянии найти алгоритмы, которые помогут вам рассчитать правильное значение. Я считаю, что некоторые разработчики используютDateTime.FromOADate() как помощник.

Так жеCell класс имеетDataType свойство как число по умолчанию. Так что, если этоноль, этоs число, которое включает даты в нашем случае.

Вы переходите к таблице общих строк только тогда, когда сохраненная дата предшествует эпохе (в данном случае 1 января 1900 года). И тогда в этом случае CellValue класса Cell хранит индекс в таблице общих строк.

 Santhos11 июн. 2014 г., 13:30
Теперь у меня есть опыт работы как с библиотекой EPPlus, так и с Open SDK, и для всех будущих зрителей я хотел бы заявить, что использование EPPlus - очень хороший выбор (лучше, чем использование Open SDK), если вы не хотите делать что-то, что не поддерживается EPPlus.
 Santhos01 нояб. 2012 г., 19:24
Хорошо, разбор с FromOADate на самом деле работает!
 Csaba Toth26 сент. 2013 г., 18:11
Это отвечает на это:dotnetperls.com/fromoadate
 Csaba Toth26 сент. 2013 г., 18:57
У меня есть одна проблема: как различить встроенные числа и числа, которые должны быть датами? В обоих случаях для меняcell.DataType являетсяnullи у меня есть строковое представление числа в тексте.
 Csaba Toth26 сент. 2013 г., 18:09
@ Сантос, нужно ли что-то делать, кромеFromOADate? @VincentTan упоминает это только как "вспомогательный метод ".

Ваш ответ на вопрос