Date NumberingFormats总是空的,为什么?

Date NumberingFormats总是空的,为什么?,date,openxml,xlsx,Date,Openxml,Xlsx,我正在编写一个使用OpenXML读取excel文件的程序。该文件还包含日期,因此我需要一个能够识别日期的函数。在stackoverflow上,我找到了以下解决方案: 我曾尝试将其应用于我的代码,但每次都会出现以下错误: OpenXML_Prova.exe中发生类型为“System.NullReferenceException”的未处理异常 其他信息:对象引用未设置为对象的实例 在GetDateTimeCellFormats的第一行,其中NumberingFormats似乎总是空的 以下是完整的代

我正在编写一个使用OpenXML读取excel文件的程序。该文件还包含日期,因此我需要一个能够识别日期的函数。在stackoverflow上,我找到了以下解决方案:

我曾尝试将其应用于我的代码,但每次都会出现以下错误:

OpenXML_Prova.exe中发生类型为“System.NullReferenceException”的未处理异常

其他信息:对象引用未设置为对象的实例

在GetDateTimeCellFormats的第一行,其中NumberingFormats似乎总是空的

以下是完整的代码:

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;



namespace OpenXML_Prova
{
    class Program
    {

        DocumentFormat.OpenXml.Spreadsheet.NumberingFormats numb = new NumberingFormats();

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

        static void Main(string[] args) {
            Program prova = new Program();
            prova.ReadFile();
        }

        void ReadFile()
        {

            var filePath = @"C:\\Users\\m.p\\Desktop\\report_fatturato_brevissimo.xlsx";
            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (SpreadsheetDocument doc = SpreadsheetDocument.Open(fs, false))
                {
                    WorkbookPart workbookPart = doc.WorkbookPart;
                    SharedStringTablePart sstpart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();
                    SharedStringTable sst = sstpart.SharedStringTable;

                    WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
                    Worksheet sheet = worksheetPart.Worksheet;

                    var cells = sheet.Descendants<Cell>();
                    var rows = sheet.Descendants<Row>();

                    Console.WriteLine("Row count = {0}", rows.LongCount());
                    Console.WriteLine("Cell count = {0}", cells.LongCount());

                    // Or... via each row
                    foreach (Row row in rows)
                    {
                        foreach (Cell c in row.Elements<Cell>())
                        {
                            if ((c.DataType != null) && (c.DataType == CellValues.SharedString))
                            {
                                int ssid = int.Parse(c.CellValue.Text);
                                string str = sst.ChildElements[ssid].InnerText;
                                Console.Write/*Line*/(/*"Shared string {0}: {1}", ssid, */str + "\t");
                            }
                            else
                            {
                                if (IsDateTimeCell(workbookPart, c) == true)
                                {
                                    int ssid = int.Parse(c.CellValue.Text);
                                    DateTime date = DateTime.FromOADate(Double.Parse(c.CellValue.Text));
                                    Console.Write/*Line*/(/*"Shared string {0}: {1}", ssid, */date + "\t");
                                }
                                else if (c.CellValue != null)
                                {
                                    Console.Write/*Line*/(/*"Cell contents: {0}", */c.CellValue.Text + "\t");
                                }
                            }
                        }
                        Console.WriteLine("");
                    }
                }
            }
            Console.Read();
        }


        public static Dictionary<uint, NumberingFormat> GetDateTimeCellFormats(WorkbookPart wbPart)
        {

//Error on the following instruction: NumberingFormats seems to be always null 
            var dateNumberFormats = wbPart.WorkbookStylesPart.Stylesheet.NumberingFormats
                .Descendants<NumberingFormat>()
                .Where(nf => dateTimeFormatRegex.Match(nf.FormatCode.Value).Success)
                .ToDictionary(nf => nf.NumberFormatId.Value);

            var cellFormats = wbPart.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 wbPart, Cell cell)
        {
            if (cell.StyleIndex == null)
                return false;

            var dateTimeCellFormats = GetDateTimeCellFormats(wbPart);

            return dateTimeCellFormats.ContainsKey(cell.StyleIndex);
        }


    }
}
Excel用于电子表格单元格中的基本格式。默认日期时间格式是这些内置类型的一部分

只有使用Excel自定义格式创建新格式时,这些格式才会包含在样式表的NumberingFormats部分中

我建议您像下面这样包装代码,以检查NumberingFormats,避免出现NullReferenceException

如果wbPart.Workbookstypespart.Stylesheet.NumberingFormats!=空的{

然后需要添加一些代码来检测日期时间格式。 这将决定可能的日期时间样式。有关提供更多详细信息的规范的参考,请参阅上面的一些注释和第一个链接