Question

I am trying to get NPOI to work with ASP.NET (C#) and I want to read an excel file and put it in a DataSet. Here is the code I attempted:

public static DataTable getExcelData(string FileName, string strSheetName)
{
    DataTable dt = new DataTable();
    HSSFWorkbook hssfworkbook;
    using (FileStream file = new FileStream(FileName, FileMode.Open, FileAccess.Read))
    {
        hssfworkbook = new HSSFWorkbook(file);
    }

    ISheet sheet = hssfworkbook.GetSheet(strSheetName);
    System.Collections.IEnumerator rows = sheet.GetRowEnumerator();

    while (rows.MoveNext())
    {
        IRow row = (HSSFRow)rows.Current;

        if (dt.Columns.Count == 0)
        {
            for (int j = 0; j < row.LastCellNum; j++)
            {
                dt.Columns.Add(row.GetCell(j).ToString());
            }

            continue;
        }

        DataRow dr = dt.NewRow();
        for (int i = 0; i < row.LastCellNum; i++)
        {
            ICell cell = row.GetCell(i);

            if (cell == null)
            {
                dr[i] = null;
            }
            else
            {
                dr[i] = cell.ToString();
            }
        }
        dt.Rows.Add(dr);
    }

    return dt;
}

The Error that I get is

+       $exception  {"Object reference not set to an instance of an object."}   System.Exception {System.NullReferenceException}

The odd thing is that this actually works with 2 excel files that I have, but when I put in a third one it crashes with that error.

Was it helpful?

Solution

This returns null if strSheetName isn't found:

ISheet sheet = hssfworkbook.GetSheet(strSheetName);

try:

for( int iSheet = 0; iSheet < hssfworkbook.NumberOfSheets; ++iSheet )
{
    ISheet sheet = hssfworkbook.GetSheetAt(iSheet); // could cast to HSSFSheet
    String strSheetNameActual = sheet.SheetName;
}

Then figure out how you want to compare strSheetName to strSheetNameActual or which sheets you want to process and how.

OTHER TIPS

Try using this:

for (int j = row.FirstCellNum; j < row.LastCellNum; j++)

and

for (int i = row.FirstCellNum; i < row.LastCellNum; i++)

Instead of:

for (int j = 0; j < row.LastCellNum; j++)

and

for (int i = 0; i < row.LastCellNum; i++)

Also, make sure that you manage the case when the cells on the first row are null:

if (dt.Columns.Count == 0)
{
    int empty = 0;
    for (int j = row.FirstCellNum; j < row.LastCellNum; j++)
    {
        ICell cell = row.GetCell(j);
        if (cell == null)
        {
            dt.Columns.Add(String.Format("emptyColumnName_{0}", empty++));
        }
        else
        {
            dt.Columns.Add(row.GetCell(j).ToString());
        }
    }
    continue;
}

If you always want to read from the first sheet (probably, to get rid of the second method parameter, the sheet name, which is also the cause of your error), you may use:

// rest of the method's code
ISheet sheet = hssfworkbook.GetSheetAt(0);
if (sheet == null)
    return dt;
var rows = sheet.GetRowEnumerator();
// rest of the method's code
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top