Unity3D——在Unity中读写Excel正常,但是将Unity程序打包为exe后,读写Excel发生NullReferenceException”问题解决(附读写Excel的代码)

问题解决其实很简单,但是我走了弯路,记录下解决的过程,这也是写代码的乐趣所在。
为实现在Unity3D中读写Excel,我开始仅仅使用了以下两个dll文件:
在这里插入图片描述
在Unity Editor中读写Excel完全正常,但是RT,打包成exe后报错如下:
在这里插入图片描述
很气,打包成exe后报错连错在哪行代码都不知道,只知道肯定用了某个值为null的变量。我开始还一直在想办法想怎么才能知道错误发生在哪行代码。我发现在Unity Editor中一样的NullReferenceException是给出了具体代码行号的,为什么打包成exe后没有了呢。然后我忽然想通了,感觉自己犯了个低级错误,打包成exe后报错是不可能有具体行号的,因为C#作为一种介于解释型和编译型之间的语言,打包成exe之后其代码已经由.net的语言编译器转化为.net目标代码了,根本不是我写代码时候的样子了。于是我实在一点头绪都没有,只能用了个笨办法,我在出错的这个方法中定义一个初值为0的整型变量i,每执行一行代码就让i++,并且在catch中提示错误的时候显示i的值,这样我就知道了错误原来发生在这里:

IExcelDataReader iExcelDR = ExcelReaderFactory.CreateOpenXmlReader(fs);
DataSet ds = iExcelDR.AsDataSet();  

经过检查发现DataSet对象ds的值为null.
OK,那它为什么会为null呢。我先看了这篇帖子:帖子1
里面说了几种从IExcelDataReader读取数据的方法,我都试了,还是一样的NullReferenceException。但是这个帖子里面又给了个github的链接,这是我看的第二个帖子:帖子2
可是我发现这个帖子里面还是没有我想要的答案。这时我在帖子1的评论区里面发现了一个链接:帖子3

在这里插入图片描述
这时我才知道,原来我少添加了以上几个dll文件。在安装路径下的\Editor\Data\Mono\lib\mono\unity即可找到这几个dll文件。这是我的路径:在这里插入图片描述
最后附上读写Excel的代码,省略了参数和返回值:
读写Excel所用的引用:

using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Data;
using UnityEngine;
using Excel;
using OfficeOpenXml;
using System.Drawing;

读Excel:

public static void ReadExcel()
{
     try
     {
          string ExcelPath = "";//(Excel的路径)
          string UserInfo = "";
          FileStream fs = File.Open(Excel_Path, FileMode.Open, FileAccess.Read, FileShare.Read);
          //这里要注意“.xlsx”格式的文件要使用CreateOpenXmlReader;“.xls”格式的文件要使用CreateBinaryReader
          IExcelDataReader iExcelDR = ExcelReaderFactory.CreateOpenXmlReader(fs);
          DataSet ds = iExcelDR.AsDataSet();
          //0表示是sheet1,读取sheet1的总行数和总列数
          int columns = ds.Tables[0].Columns.Count; //总列数
          int rows = ds.Tables[0].Rows.Count;       //总行数
          for (int i = 0; i < rows; i++)
          {
               //读取每行的第二列的数据,表示行和列的下标均从0开始               
               string Str = Convert.ToString(ds.Tables[0].Rows[i][1]);
          }
      }
      catch (Exception e)
      {
           MessageBox.Show(e + " Exception caught.  ", "提示", SystemFonts.FormTextFont);
           return null;//表示有异常
      }
}

向Excel中写入数据:

        public static void WriteExcel()
        {
            //获取要创建Excel文件的路径
            string path = ExcelPath;
            //该路径的文件是否存在的标识符
            bool IsExist = true;
            FileInfo newFile = new FileInfo(path);
            //如果文件不存在 则先新建一个文件 添加sheet和表头
            if (!newFile.Exists)
            {
                //创建一个新的excel文件
                newFile = new FileInfo(path);
                IsExist = false;
            }
            //通过ExcelPackage打开文件
            using (ExcelPackage package = new ExcelPackage(newFile))
            {
                ExcelWorksheet worksheet;
                if (IsExist == false)//如果文件不存在,则为新建的Excel表添加sheet和表头
                {
                    worksheet = package.Workbook.Worksheets.Add("Sheet1");
                    worksheet.Cells[1, 1].Value = "第一列表头";
                    worksheet.Cells[1, 2].Value = "第二列表头";
                    worksheet.Cells[1, 3].Value = "第三列表头";
                    worksheet.Cells[1, 4].Value = "第四列表头";
                }
                else//如果文件存在 直接获取sheet
                {
                    //获取Sheet1,以向其中写入数据
                    worksheet = package.Workbook.Worksheets["Sheet1"];
                }
                //遍历第一列 找到第一个空白行 然后再写入数据
                int i = 1;
                while (Convert.ToString(worksheet.Cells[i, 1].Value) != "")
                {
                    i++;
                }
                //此时第i行即为第一个空白行  接下来在该行写入数据
                //此处要注意 获取单元格的时候 行和列的序号都是从1开始的 行前列后
                //第一列写入数据
                worksheet.Cells[i, 1].Value = "第一列数据";
                //第二列写入数据
                worksheet.Cells[i, 2].Value = "第二列数据"
                //第三列写入数据
                worksheet.Cells[i, 3].Value = "第三列数据"
                //第四列写入数据   
                worksheet.Cells[i, 4].Value = "第四列数据"                
                //保存excel
                package.Save();
            }
        }

欢迎留言交流指正。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值