【问题标题】:Trying to read excel file with epplus and getting System.NullException error?尝试使用 epplus 读取 excel 文件并出现 System.NullException 错误?
【发布时间】:2018-08-22 17:39:57
【问题描述】:

编辑

根据下面的回复,我遇到的错误可能会也可能不会导致我无法读取我的 excel 文件。也就是说,我没有从下面给出的 for 循环中的 worksheet.Cells[row,col].Value 行获取数据。

问题

我正在尝试从 Excel 文件中返回包含信息的 DataTable。具体来说,我相信它是 2013 年 excel 的 xlsx 文件。请看下面的代码:

private DataTable ImportToDataTable(string Path)
        {
            DataTable dt = new DataTable();
            FileInfo fi = new FileInfo(Path);

            if(!fi.Exists)
            {
                throw new Exception("File " + Path + " Does not exist.");
            }

            using (ExcelPackage xlPackage = new ExcelPackage(fi))
            {
                //Get the worksheet in the workbook 
                ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets.First();

                //Obtain the worksheet size 
                ExcelCellAddress startCell = worksheet.Dimension.Start;
                ExcelCellAddress endCell = worksheet.Dimension.End;

                //Create the data column 
                for(int col = startCell.Column; col <= endCell.Column; col++)
                {
                    dt.Columns.Add(col.ToString());
                }


                for(int row = startCell.Row; row <= endCell.Row; row++)
                {
                    DataRow dr = dt.NewRow(); //Create a row
                    int i = 0; 
                    for(int col = startCell.Column; col <= endCell.Column; col++)
                    {
                        dr[i++] = worksheet.Cells[row, col].Value.ToString();
                    }
                    dt.Rows.Add(dr);

                }
            }

            return dt;


        }

错误

这就是事情变得奇怪的地方。我可以在startCellendCell 中看到正确的值。但是,当我查看worksheet 时,我在Cells 下偷看了一眼,我看到了一些我不明白的东西:

worksheet.Cells.Current' threw an exception of type 'System.NullReferenceException

尝试

  • 使用常规字段重新格式化我的 Excel。
  • 确保我的 Excel 中没有字段为空
  • RTFM 的 epplus 文档。没有任何迹象表明这个错误。
  • 查看了 stackoverflow 上的 EPPlus 错误。我的问题是独一无二的。

老实说,我无法弄清楚这个错误的真正含义是什么?我的格式有问题吗? epplus有什么问题吗?我在这里读过人们对 2013 xlsx 和 eeplus 没有任何问题,我只是想逐行解析 excel 文件。如果有人可以帮助我了解此错误的含义以及如何纠正它。我将不胜感激。我花了很长时间试图弄清楚这一点。

【问题讨论】:

  • Current 可能暗示你标记一个范围!?,然后你有一个当前单元格。这是否会影响您的程序,看不到对 Current 的任何访问权限,或者当您检查 Cells 对象中的某些内容时会引发异常,这是否会影响您?这实际上在 .net 环境中很常见
  • 是的,这确实会影响我的程序。在下面的循环中枚举时,我看不到 Value。我认为这个错误是原因。
  • @doctor 这不是复制品。我不是在问为什么我在这里有一个空值,而是为什么它会导致我在底部的枚举失败。我看不到Value。我会更准确地编辑问题。谢谢。 :)
  • 感谢大家到目前为止的回复。为所有参与的人投票。

标签: c# excel epplus


【解决方案1】:

当我们给予时:

dr[i++] = worksheet.Cells[row, col].Value.ToString();

它在该列搜索值,如果该列为空,则给出 Null 引用错误。

试试吧:

dr[i++] = worksheet.Cells[row, col].Text;

希望这会有所帮助

【讨论】:

    【解决方案2】:

    就像@Thorians 说的那样, current 确实是在您枚举单元格时使用的。如果你想以最纯粹的形式使用它并且实际上能够调用current,那么你需要这样的东西:

    using (var pck = new ExcelPackage(existingFile))
    {
        var worksheet = pck.Workbook.Worksheets.First();
    
        //this is important to hold onto the range reference
        var cells = worksheet.Cells;
    
        //this is important to start the cellEnum object (the Enumerator)
        cells.Reset();
    
        //Can now loop the enumerator
        while (cells.MoveNext())
        {
            //Current can now be used thanks to MoveNext
            Console.WriteLine("Cell [{0}, {1}] = {2}"
                , cells.Current.Start.Row
                , cells.Current.Start.Column
                , cells.Current.Value);
        }
    }
    

    请注意,您必须创建一种local 集合cells 才能正常工作。否则Current 将在您尝试 `worksheet.cells.current' 时为空

    但使用 ForEach 并让 CLR 为您完成工作会更简单。


    更新:基于 cmets。您的代码应该可以正常工作,可以是您的 excel 文件吗:

    [TestMethod]
    public void Current_Cell_Test()
    {
        //http://stackoverflow.com/questions/32516676/trying-to-read-excel-file-with-epplus-and-getting-system-nullexception-error
    
        //Throw in some data
        var datatable = new DataTable("tblData");
        datatable.Columns.AddRange(new[] { new DataColumn("Col1", typeof (int)), new DataColumn("Col2", typeof (int)),new DataColumn("Col3", typeof (object)) });
    
        for (var i = 0; i < 10; i++)
        {
            var row = datatable.NewRow(); row[0] = i; row[1] = i * 10; row[2] = Path.GetRandomFileName(); datatable.Rows.Add(row);
        }
    
        //Create a test file
        var fi = new FileInfo(@"c:\temp\test1.xlsx");
        if (fi.Exists)
            fi.Delete();
    
        using (var pck = new ExcelPackage(fi))
        {
            var worksheet = pck.Workbook.Worksheets.Add("Sheet1");
            worksheet.Cells.LoadFromDataTable(datatable, true);
            pck.Save();
        }
    
        var dt = new DataTable();
    
        using (ExcelPackage xlPackage = new ExcelPackage(fi))
        {
            //Get the worksheet in the workbook 
            ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets.First();
    
            //Obtain the worksheet size 
            ExcelCellAddress startCell = worksheet.Dimension.Start;
            ExcelCellAddress endCell = worksheet.Dimension.End;
    
            //Create the data column 
            for (int col = startCell.Column; col <= endCell.Column; col++)
            {
                dt.Columns.Add(col.ToString());
            }
    
    
            for (int row = startCell.Row; row <= endCell.Row; row++)
            {
                DataRow dr = dt.NewRow(); //Create a row
                int i = 0;
                for (int col = startCell.Column; col <= endCell.Column; col++)
                {
                    dr[i++] = worksheet.Cells[row, col].Value.ToString();
                }
                dt.Rows.Add(dr);
    
            }
        }
    
        Console.Write("{{dt Rows: {0} Columns: {1}}}", dt.Rows.Count, dt.Columns.Count);
    }
    

    在输出中给出这个:

    {Rows: 11, Columns: 3}
    

    【讨论】:

    • 谢谢。你说的对。我试图在我的代码中枚举我的单元格,但我失败了。特别是dr[i++] = worksheet.Cells[row, col].Value 也没有。这与Current 有关还是我真的有一个单独的问题并且没有意识到?
    • @hlyates Humm..这很有趣。您的代码应该按原样工作。看我上面的更新。您的确切错误是什么?
    【解决方案3】:

    Current 是枚举时的当前范围。

    当它不在枚举范围内使用时,在调试检查中抛出异常没有任何问题。

    代码示例:

    var range = ws.Cells[1,1,1,100];
    foreach (var cell in range)
    {
        var a =  range.Current.Value;  // a is same as b
        var b = cell.Value;         
    }
    

    【讨论】:

    • 当我使用worksheet.Cells[row,col].value 枚举时,我似乎无法访问我的单元格。如果我的理解正确,这是因为我没有正确使用range
    • 是的,我认为你应该避免 Current ,而是使用 cell
    【解决方案4】:

    我在阅读 excel 文件时也遇到了同样的问题,并且提供的解决方案都不适合我。这是工作代码:

    public void readXLS(string FilePath)
    {
        FileInfo existingFile = new FileInfo(FilePath);
        using (ExcelPackage package = new ExcelPackage(existingFile))
        {
            //get the first worksheet in the workbook
            ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
            int colCount = worksheet.Dimension.End.Column;  //get Column Count
            int rowCount = worksheet.Dimension.End.Row;     //get row count
            for (int row = 1; row <= rowCount; row++)
            {
                for (int col = 1; col <= colCount; col++)
                {
                    Console.WriteLine(" Row:" + row + " column:" + col + " Value:" + worksheet.Cells[row, col].Value.ToString().Trim());
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 2018-05-30
      相关资源
      最近更新 更多