tutorial open office microsoft documentformat c#-4.0 datetime openxml openxml-sdk

c# 4.0 - office - ¿Cómo distinguir los números en línea de los números de fecha de automatización OLE en OpenXML SpreadSheet?



openxml microsoft (1)

Me encontré con un problema similar y no es fácil verificar si una celda contiene un valor de fecha / hora, ver Usar el formato de celda para determinar que una celda contiene el valor de fecha / hora , pero el problema no termina con los formatos de números incorporados. Necesitaba manejar formatos personalizados también. No hay utilidades en OpenXML SDK 2.5 para ayudar, así que tuve que escribir las mías (no es compatible con los formatos tailandeses de fecha / hora).

public class ExcelHelper { static uint[] builtInDateTimeNumberFormatIDs = new uint[] { 14, 15, 16, 17, 18, 19, 20, 21, 22, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 45, 46, 47, 50, 51, 52, 53, 54, 55, 56, 57, 58 }; static Dictionary<uint, NumberingFormat> builtInDateTimeNumberFormats = builtInDateTimeNumberFormatIDs.ToDictionary(id => id, id => new NumberingFormat { NumberFormatId = id }); static Regex dateTimeFormatRegex = new Regex(@"((?=([^[]*/[[^[/]]*/])*([^[]*[ymdhs]+[^/]]*))|.*/[(h|mm|ss)/].*)", RegexOptions.Compiled); public static Dictionary<uint, NumberingFormat> GetDateTimeCellFormats(WorkbookPart workbookPart) { var dateNumberFormats = workbookPart.WorkbookStylesPart.Stylesheet.NumberingFormats .Descendants<NumberingFormat>() .Where(nf => dateTimeFormatRegex.Match(nf.FormatCode.Value).Success) .ToDictionary(nf => nf.NumberFormatId.Value); var cellFormats = workbookPart.WorkbookStylesPart.Stylesheet.CellFormats .Descendants<CellFormat>(); var dateCellFormats = new Dictionary<uint, NumberingFormat>(); uint styleIndex = 0; foreach (var cellFormat in cellFormats) { if (cellFormat.ApplyNumberFormat != null && cellFormat.ApplyNumberFormat.Value) { if (dateNumberFormats.ContainsKey(cellFormat.NumberFormatId.Value)) { dateCellFormats.Add(styleIndex, dateNumberFormats[cellFormat.NumberFormatId.Value]); } else if (builtInDateTimeNumberFormats.ContainsKey(cellFormat.NumberFormatId.Value)) { dateCellFormats.Add(styleIndex, builtInDateTimeNumberFormats[cellFormat.NumberFormatId.Value]); } } styleIndex++; } return dateCellFormats; } // Usage Example public static bool IsDateTimeCell(WorkbookPart workbookPart, Cell cell) { if (cell.StyleIndex == null) return false; var dateTimeCellFormats = ExcelHelper.GetDateTimeCellFormats(workbookPart); return dateTimeCellFormats.ContainsKey(cell.StyleIndex); } }

Tengo que consumir algunos documentos xlsx . He leído Leer una fecha de xlsx usando open xml sdk y http://www.dotnetperls.com/fromoadate . La mayoría de mis columnas son textos (cadenas compartidas), pero hay algunos números (números enteros), y también tengo algunas fechas y fechas. Estoy usando OpenXML SDK 2.5.

Mi problema es que no sé cómo distinguir los números reales de las fechas. Ambos tienen DataType de null , y la representación numérica textual está en la propiedad Text de la celda.

Cierto código:

using (var xlsxStream = assembly.GetManifestResourceStream("Checklist.xlsx")) using (var spreadsheetDocument = SpreadsheetDocument.Open(xlsxStream, false)) { var workbookPart = spreadsheetDocument.WorkbookPart; var sharedStringTable = workbookPart.SharedStringTablePart.SharedStringTable; var worksheetPart = workbookPart.WorksheetParts.First(); var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First(); string text; foreach (Row r in sheetData.Elements<Row>()) { foreach (Cell c in r.Elements<Cell>()) { if (c.CellValue != null) { text = c.CellValue.Text; if (c.DataType != null) { if (c.DataType.Value == CellValues.SharedString) { int tableIndex = int.Parse(text); text = sharedStringTable.ChildElements[tableIndex].InnerText; } // note: the date cells do not have c.DataType.Value == CellValues.Date // Their c.DataType is null, if they are OLE Automation date numbers } // So here I am, and I''d need to know if the number supposed to be an // OLE Automation date or a number, so I can transform it if needed. //if (it''s a date) // <- ????? //{ // double dateDouble = double.Parse(text); // DateTime dateTime = DateTime.FromOADate(dateDouble); // text = dateTime.ToShortDateString(); //} Console.Write(text + " "); } else { Console.Write("NULL" + " "); } } Console.WriteLine(); } Console.WriteLine(); Console.ReadKey();