Unity读取Excel数据的方法

准备工作

首先下载Excel.dll ,ICSharpCode.SharpZioLib.dll ,System.Data.dll 这些类库下载下来 放在Unity目录下的Plugin目录下,没有的话就新建一个


接着找到需要使用的表

Unity读取Excel表_xml


目的

准备工作做完之后,我们要看看我们根据这个表,要的结果是什么?我们会把表中的内容读取到一个对应的class实例(ItemManager)中,然后将这个实例生成一个Asset资源,解释一下 每次代码编译都会读取一下Excel表中的内容 从而实例出asset,读取这个肯定要比直接读取Excel快的多。

如图:Unity读取Excel表_xml_02

会发现这个Asset包含了表里的所有内容,然后我们就可以使用这个Asset来获取我们需要的数据。比如将这个Asset文件放在Resources文件夹下,用如下代码遍历:

登录后复制

public GameObject A;  //这个A 是一个gameobject 可以随意修改  也可以Excel表中配置路径 自由发挥    void Start()    {        ItemManager man = Resources.Load<ItemManager>("DataAssets/Unity_list");        foreach (Item i in man.dataArray)        {            Debug.Log(i.itemName + "---" + i.itemPos);            GameObject go = GameObject.Instantiate(A, i.itemPos, Quaternion.identity);            go.name = i.itemName;            go.transform.eulerAngles = i.itemPos;        }    }1.2.3.4.5.6.7.8.9.10.11.12.

打出的Log如下:

Unity读取Excel表_表数据_03

当然我们也可以将这个Asset打成一个ab包来读取。

知识点:

1.ScriptableObject:我们要将一个class的实例生成一个UnityEngine.Object文件,然后将这个Object生成为Asset文件,我们的class需要继承ScriptableObject。

2.Serializable:可以序列化一个类,使这个被序列化的对象在Inspector面板上显示, 并可以赋予相应的值

3.读取excel的操作和打包AB一样,不能在程序运行时执行,代码要放在Editor文件夹下。

定义类

我们首先需要定义两个类,第一个类用来存放每行的表数据(Item)该类需要添加Serializable字段,才能在Asset中显示数据。

第二个类用来存放前者的数组即所有的表数据(ItemManager)。该类即要生成Object的类,需要继承ScriptableObject

新建工具类 读取表内容  当然可以设置第几张表

登录后复制

using UnityEngine;using System.Data;using System.IO;using Data;using Excel;namespace Data{    [System.Serializable]    public class Item    {        public string itemName;        public Vector3 itemPos;    }    public class ItemManager : ScriptableObject    {        public Item[] dataArray;    }}namespace EditorTool{    public class ExcelConfig    {        /// <summary>        /// 存放excel表文件夹的的路径,本例xecel表放在了"Assets/Excels/"当中        /// </summary>        public static readonly string excelsFolderPath = Application.dataPath + "/Excels/";        /// <summary>        /// 存放Excel转化CS文件的文件夹路径        /// </summary>        public static readonly string assetPath = "Assets/Resources/DataAssets/";    }    public class ExcelTool    {        /// <summary>        /// 读取表数据,生成对应的数组        /// </summary>        /// <param name="filePath">excel文件全路径</param>        /// <returns>Item数组</returns>        public static Item[] CreateItemArrayWithExcel(string filePath)        {            //获得表数据            int columnNum = 0, rowNum = 0;            DataRowCollection collect = ReadExcel(filePath, ref columnNum, ref rowNum);            //根据excel的定义,第三行开始才是数据            Item[] array = new Item[rowNum - 2];            for (int i = 2; i < rowNum; i++)            {                Item item = new Item();                //解析每列的数据                item.itemName = collect[i][0].ToString();                item.itemPos = new Vector3(float.Parse(collect[i][1].ToString()), float.Parse(collect[i][2].ToString()), float.Parse(collect[i][3].ToString()));                array[i - 2] = item;            }            return array;        }        /// <summary>        /// 读取excel文件内容        /// </summary>        /// <param name="filePath">文件路径</param>        /// <param name="columnNum">行数</param>        /// <param name="rowNum">列数</param>        /// <returns></returns>        static DataRowCollection ReadExcel(string filePath, ref int columnNum, ref int rowNum)        {            FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);            IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);            DataSet result = excelReader.AsDataSet();            //Tables[0] 下标0表示excel文件中第一张表的数据            columnNum = result.Tables[0].Columns.Count;            rowNum = result.Tables[0].Rows.Count;            return result.Tables[0].Rows;        }    }}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.57.58.59.60.61.62.63.64.65.66.67.68.69.70.71.72.73.74.75.76.

我们将拿到的数据存放在ItemManager当中,并生成一个Asset:

登录后复制

using System.IO;using Data;using EditorTool;using UnityEditor;using UnityEditor.Callbacks;using UnityEngine;public class ExcelBuild : Editor{    [MenuItem("CustomEditor/CreateItemAsset")]    [DidReloadScripts]// 现代代码自动编译会执行此方法    public static void CreateItemAsset()    {        ItemManager manager = ScriptableObject.CreateInstance<ItemManager>();        //赋值        manager.dataArray = ExcelTool.CreateItemArrayWithExcel(ExcelConfig.excelsFolderPath + "Unity_list.xlsx");        //确保文件夹存在        if (!Directory.Exists(ExcelConfig.assetPath))        {            Directory.CreateDirectory(ExcelConfig.assetPath);        }        //asset文件的路径 要以"Assets/..."开始,否则CreateAsset会报错        string assetPath = string.Format("{0}{1}.asset", ExcelConfig.assetPath, "Unity_list");        //生成一个Asset文件        AssetDatabase.CreateAsset(manager, assetPath);        AssetDatabase.SaveAssets();        AssetDatabase.Refresh();    }}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.

这样我们就大功告成了!!!在Unity菜单项,选择我们自定义的菜单CustomEditor->CreateItemAsset(目前的asset 每次代码编译都会重新生成一遍)。即可生成我们需要的Asset。

附加

备注:上面这种方法,我们自己手动根据对应的表写对应的类,然后针对性解析。但是如果我们有几十个表,那么就会显得很愚蠢。所以有个优化方案就是,我们在表中存好字段名称和字段类型,然后遍历所有的表读取这两个信息,用代码自动生成我们需要的.cs文件。当类都生成好后,再去遍历表解析数据,利用反射存入对应的类中,然后生成对应的Asset。

Unity读取Excel表_数据_04

注意:在AssetDatabase.CreateAsset()中,我们要传的路径应该是"Assets/"开头的Unity路径,而不是Windows中的全路径,类似于"E://..."。否则会报如下错误:Couldn't create asset file!

Unity读取Excel表_数据_05

注意:在ScriptableObject类中,基本数据类型以外的成员类型需要加 SerializeField 关键字,自定义数据类型被ScriptableObject对象使用的时候,该类需要加 Serializable 关键字。如果没有加的话生成的Asset资源Inspector窗口就无法看见对应数据。



补充:

System.Data.dll如果冲突的话,删除即可。

经测试发现,分以下两种情况:

1. 如果xlsx文件的后缀为.xlsx,读取的代码应该为

登录后复制

IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);1.

若使用CreateBinaryReader读取,则在excelReader.AsDataSet();会报错NullReferenceException: Object reference not set to an instance of an object

2.如果xlsx文件的后缀为.xls,读取的代码应该为

登录后复制

IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);1.

若使用CreateOpenXmlReader读取,则在CreateOpenXmlReader处会报错ArgumentNullException: Value cannot be null.




免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空