web-dev-qa-db-ja.com

epplusでExcelファイルを読み取ろうとすると、System.NullExceptionエラーが発生しますか?

編集

以下の返信に基づいて、私が経験しているエラーが原因で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に何か問題がありますか?私はここで人々がeeplusで2013xlsxに問題がなかったことを読みました、そして私は行ごとにExcelファイルを解析しようとしているだけです。誰かが私がこのエラーの意味とそれを修正する方法を明らかにするのを手伝ってくれるなら。よろしくお願いします。私はこれを理解しようとかなり長い時間を費やしてきました。

5
hlyates

@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を作成する必要があることに注意してください。それ以外の場合、 `worksheet.cells.current 'を試した場合、Currentはnullになります

ただし、ForEachを使用して、CLRに作業を任せる方が簡単です。


更新:コメントに基づく。あなたのコードはそのままでうまくいくはずです、それはあなたの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}
1
Ernie S

私たちが与えるとき:

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

その列で値を検索します。列が空の場合、Null参照エラーが発生します。

代わりに試してください:

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

これが役立つことを願っています

3
kumar gaurav

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

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());
            }
        }
    }
}
0
Suresh Kamrushi