tutorial open office documentformat c# date datetime openxml openxml-sdk

c# - office - open xml sdk tutorial



Leyendo una fecha de xlsx usando xml sdk abierto (5)

Tengo una fecha en el formato "4/5/2011" (mes / día / año) en un archivo xlsx en una de las celdas. Estoy tratando de analizar el archivo y cargar esos datos en algunas clases.

Hasta aquí la parte donde analizo la celda se ve así:

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

Esperaba que esa fecha fuera un cell.DataType. La verdad es que cuando se analiza la celda con la fecha "4/5/2011", el valor de cell.DataType es nulo y el valor de la celda es "40638" y no es un índice de la tabla de cadenas compartidas. (He intentado eso antes y terminó con una excepción).

¿Algunas ideas? Gracias


Agregando mi valor de 2 peniques. Estoy procesando una plantilla, así que sé que una celda determinada está destinada a ser un DateTime. Así que termino en este método con un parámetro de cadena excelDateTime que contiene el valor de celda, que normalmente será un número OADate como "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);

Mi problema es que el usuario final está en Alemania, y como este es un sitio web, hemos establecido Thread.CurrentThread.CurrentCulture and Thread.CurrentThread.CurrentUICulture en "DE-de". Y cuando llamas a double.TryParse , usa la cultura para analizar el número. Por lo tanto, esta línea: double.TryParse("42540.041666666664", out oaDate) sí funciona, pero devuelve 42540041666666664 ya que en Alemania el punto es un separador de grupo. DateTime.FromOADate luego falla porque el número está fuera del rango ( minOaDate = -657435.0, maxOaDate = +2958465.99999999 ).

Esto me hace pensar que:

  1. independientemente de la ubicación en la máquina de un usuario, el documento OpenXML contiene números con formato en una ubicación predeterminada (US invariant, en cualquier caso, con el punto como separador decimal). He buscado, pero no he encontrado la especificación para esto.
  2. al hacer double.TryParse en una posible cadena OADate, deberíamos hacerlo con double.TryParse(excelDateTimeAsString, NumberStyles.Any, CultureInfo.InvariantCulture, out oaDateAsDouble)) . Estoy usando CultureInfo.InvariantCulture, pero debería ser el punto 1, que no estoy seguro.

Cada celda tiene 2 propiedades r (CellReference) ys (StyleIndex)

StyleIndex para números es 2 y para fecha es 3

Fecha en que está en ODate y puede convertir a formato de cadena

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


Open XML almacena las fechas como el número de días desde el 1 de enero de 1900. Bueno, omitir el incorrecto 29 de febrero de 1900 como un día válido. Debería poder encontrar algoritmos que lo ayuden a calcular el valor correcto. Creo que algunos desarrolladores usan DateTime.FromOADate() como ayudante.

Además, la clase Cell tiene la propiedad DataType como Número por defecto. Entonces, si es nulo, es un número, que incluye fechas en nuestro caso.

Solo va a la tabla de cadenas compartidas cuando la fecha almacenada es anterior a la época (1 de enero de 1900 en este caso). Y luego, en ese caso, el valor CellValue de la clase Cell contiene el índice de la tabla de cadenas compartidas.


Tuve el mismo problema: cambié a EPPlus http://epplus.codeplex.com/

Tenga en cuenta que tiene licencia LGPL. Entonces, si necesita que su código base esté a salvo del problema de la GPL, simplemente use la biblioteca tal como está y su licencia de código base original está segura.


puedes usar DateTime.FromOADate (41690)