C# 用NPOI读取Excel的问题

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using NUnit.Framework;
using System.Text;

public class ExcelManager
{

    public List<string> _valType;
    public List<string> _valName;
    public string _className;
    public List<List<string>> _data;
    public int _invalidLine = 0;
    public int _dataIndex = -1;

    public StringBuilder _classSource;

    public void ReadExcel()
    {
        _valType = new List<string>();
        _valName = new List<string>();
        string path = null;
        _data = new List<List<string>>();

        string[] paths = Directory.GetFiles(@"./Assets/Resources/");
        foreach (var item in paths)
        {
            string extension = Path.GetExtension(item);
            if (extension == ".xlsx" || extension == ".xls")
            {
                path = item;
                break;
            }
        }

        IWorkbook workbook = null;
        FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
        if (path.IndexOf(".xlsx") > 0)
        {
            //2007版
            workbook = new XSSFWorkbook(fileStream);
        }
        else if (path.IndexOf(".xls") > 0)
        {
            //2003版
            workbook = new HSSFWorkbook(fileStream);
        }
        else
        {
            Debug.LogError("Invalid path.");
        }

        ISheet sheet = workbook.GetSheetAt(0);
        _className = sheet.SheetName.Substring(1, sheet.SheetName.Length - 1);

        IRow row = sheet.GetRow(0);
        for (int i = 0; i <= sheet.LastRowNum; ++i)
        {
            row = sheet.GetRow(i);

            if (row != null)
            {   
                //若该行首列内容以'#'开头,则为无效列
                var tmp = row.GetCell(0).ToString();
                if (tmp[0] == '#')
                {
                    ++_invalidLine;
                    continue;
                }

                for (int j = 0; j < row.LastCellNum; ++j)
                {
                    var cellValue = row.GetCell(j).ToString();

                    if (cellValue[0] == '&')
                    {
                        //内容以'&'开头则记录变量名和类型
                        int index = cellValue.IndexOf('|');
                        string tmpVarName = cellValue.Substring(1, index - 1);
                        string tmpVarType = cellValue.Substring(index + 1, cellValue.Length - (index + 1));

                        _valType.Add(tmpVarType);
                        _valName.Add(tmpVarName);
                    }
                    else
                    {
                        //否则记录数据
                        if (_data.Count < i - _invalidLine)
                        {
                            ++_dataIndex;
                            _data.Add(new List<string>());
                            _data[_dataIndex].Add(cellValue);
                        }
                        else
                        {
                            _data[_dataIndex].Add(cellValue);
                        }
                    }
                }
            }
        }

        fileStream.Close();
        workbook.Close();
    }

    public void GetClassSource()
    {
        _classSource = new StringBuilder();

        _classSource.Append("using System;\n");
        _classSource.Append("using UnityEngine;\n");
        _classSource.Append("using System.Collections;\n");
        _classSource.Append("using System.Collections.Generic;\n\n");
        _classSource.Append("public class " + _className + " : ScriptableObject\n");
        _classSource.Append("{\n");
        _classSource.Append("\t[System.Serializable]\n");
        _classSource.Append("\tpublic class Field\n");
        _classSource.Append("\t{\n");
        int len = _valType.Count;
        for (int i = 0; i < len; ++i)
        {
            _classSource.Append("\t\tpublic " + _valType[i] + " " + _valName[i] + ";\n");
        }
        _classSource.Append("\t}\n");
        _classSource.Append("\n\t[SerializeField]\n");
        _classSource.Append("\tpublic List<Field> Fields;\n");
        _classSource.Append("}\n");
    }
}

在unity中做的。
请看第69行,按照https://blog.csdn.net/dcrmg/article/details/52356236 做的,原本还好好的,能够读取第i行首列的数据,但是今天莫名其妙开始报错:Object reference not set an instance of an object.

var tmp = row.GetCell(0).ToString();我尝试用Debug.Log(row.GetCell(0).ToString())
打印,发现打印了一整列的数据。

不应该取得的是该行首列的数据吗?代码什么都没改过为啥就用不了了。

链接: https://pan.baidu.com/s/1oQ7MhWbzBqXB2iutxgRs5Q 密码: h2jr
整个工程文件

既然之前是没问题的,那多半是有不合法的数据,或者是程序没有针对不合法的数据进行容错。

在excel里看下,是不是本身数据就不对,所有的列全部挤在一行里了。另外有没有合并过单元格。

这种错误,设断点一下就可以找到哦,看看是哪里引用了NULL对像

报的错误比较明显,有对象没有正确赋值或者初始化,定位一下,看看数据或者变量有没有问题。