Unity导表工具(Excel)

原文地址:https://blog.csdn.net/qq_14903317/article/details/78637440

感谢原作者提供的思路,在原作者基础上做了一些完善,实现思路请移步原作者博客。

using System.Collections.Generic;
using System.Reflection;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System;
using UnityEngine;
using UnityEditor;
using Excel;

namespace WJExcelDataManager
{
    public class ExcelDataTool
    {
        private static string INPUT_PATH;
        public const string CODE_NAMESPACE = "WJExcelDataClass";//由表生成的数据类型均在此命名空间内
        public const string BinDataFolder = "BinConfigData";//序列化的数据文件都会放在此文件夹内,此文件夹位于Resources文件夹下用于读取数据

        private static List codeList;//存放所有生成的类的代码
        private static Dictionary> dataDict;//存放所有数据表内的数据,key:类名  value:数据

        [UnityEditor.MenuItem("开发工具/导表工具/导入全部数据")]
        public static void LoadAllExcelData()
        {
            //if (!EditorUtility.DisplayDialog("注意!!!", "导表前要关闭打开的数据表,否则会失败,是否继续?", "继续", "取消")) return;

            INPUT_PATH = PlayerPrefs.GetString(System.Environment.CurrentDirectory + "ExcelDataInputPath", "");

            if (string.IsNullOrEmpty(INPUT_PATH))
            {
                ProgressBar.HideBarWithFailInfo("\n请先设置数据表路径!");
                throw new Exception("请先设置数据表路径!");
            }

            string[] files = Directory.GetFiles(INPUT_PATH, "*.xls");
            if (files == null || files.Length == 0)
            {
                EditorUtility.DisplayDialog("注意!!!", "\n暂无可以导入的数据表!", "确定");
                EditorUtility.ClearProgressBar();
                throw new Exception("暂无可以导入的数据表!");
            }
            if (codeList == null)
            {
                codeList = new List();
            }
            else
            {
                codeList.Clear();
            }
            if (dataDict == null)
            {
                dataDict = new Dictionary>();
            }
            else
            {
                dataDict.Clear();
            }
            float step = 1f;
            foreach (string item in files)
            {
                ProgressBar.UpdataBar("正在加载 " + item, step / files.Length * 0.4f);
                step++;
                GetExcelData(item);
            }
            if (codeList.Count == 0)
            {
                EditorUtility.DisplayDialog("注意!!!", "\n暂无可以导入的数据表!", "确定");
                EditorUtility.ClearProgressBar();
                throw new Exception("暂无可以导入的数据表!");
            }
            //编译代码,生成包含所有数据表内数据类型的dll
            Assembly assembly = CompileCode(codeList.ToArray());
            //准备序列化数据
            string BinDataPath = System.Environment.CurrentDirectory + "/Assets/Resources/" + BinDataFolder;//序列化后的数据存放路径
            if (Directory.Exists(BinDataPath)) Directory.Delete(BinDataPath, true);//删除旧的数据文件
            Directory.CreateDirectory(BinDataPath);
            step = 1;
            foreach (KeyValuePair> each in dataDict)
            {
                ProgressBar.UpdataBar("序列化数据: " + each.Key, step / dataDict.Count * 0.6f + 0.399f);//0.399是为了进度条在生成所有代码以前不会走完显示完成弹窗
                step++;
                //Assembly.CreateInstance 方法 (String) 使用区分大小写的搜索,从此程序集中查找指定的类型,然后使用系统激活器创建它的实例化对象
                object container = assembly.CreateInstance(CODE_NAMESPACE + "." + each.Key);
                Type temp = assembly.GetType(CODE_NAMESPACE + "." + each.Key + "Item");
                //序列化数据
                Serialize(container, temp, each.Value, BinDataPath);
            }
            ProgressBar.UpdataBar("创建数据管理类: DataManager", 0.999f);
            ScriptGenerator.CreateDataManager(assembly);
            ProgressBar.UpdataBar("\n导表成功!", 1);
            AssetDatabase.Refresh();
            Debug.Log("导表成功!");
        }

        //数据表内每一格数据
        class ConfigData
        {
            public string Type;//数据类型
            public string Name;//字段名
            public string Data;//数据值
        }

        private static void GetExcelData(string inputPath)
        {
            FileStream stream = null;
            try
            {
                stream = File.Open(inputPath, FileMode.Open, FileAccess.Read);
            }
            catch
            {
                EditorUtility.DisplayDialog("注意!!!", "\n请关闭 " + inputPath + " 后再导表!", "确定");
                EditorUtility.ClearProgressBar();
                throw new Exception("请关闭 " + inputPath + " 后再导表!");
            }
            IExcelDataReader excelReader = null;
            if (inputPath.EndsWith(".xls")) excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
            else if (inputPath.EndsWith(".xlsx")) excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
            if (!excelReader.IsValid)
            {
                ProgressBar.HideBarWithFailInfo("\n无法读取的文件:  " + inputPath);
                EditorUtility.ClearProgressBar();
                throw new Exception("无法读取的文件:  " + inputPath);
            }
            else
            {
                do
                {
                    // sheet name
                    string className = excelReader.Name;
                    string[] types = null;//数据类型
                    string[] names = null;//字段名
                    List dataList = new List();
                    int index = 1;

                    //开始读取
                    while (excelReader.Read())
                    {
                        //这里读取的是每一行的数据
                        string[] datas = new string[excelReader.FieldCount];
                        for (int j = 0; j < excelReader.FieldCount; ++j)
                        {
                            datas[j] = excelReader.GetString(j);
                        }

                        //空行不处理
                        if (datas.Length == 0 || string.IsNullOrEmpty(datas[0]))
                        {
                            ++index;
                            continue;
                        }
                        //第4行表示类型
                        if (index == 4) types = datas;
                        //第5行表示变量名
                        else if (index == 5) names = datas;
                        //后面的表示数据
                        else if (index > 5)
                        {
                            //把读取的数据和数据类型,名称保存起来,后面用来动态生成类
                            List configDataList = new List();
                            for (int j = 0; j < datas.Length; ++j)
                            {
                                ConfigData data = new ConfigData();
                                data.Type = types[j];
                                data.Name = names[j];
                                data.Data = datas[j];
                                if (string.IsNullOrEmpty(data.Type) || string.IsNullOrEmpty(data.Data)) continue;//空的数据不处理
                                configDataList.Add(data);
                            }
                            dataList.Add(configDataList.ToArray());
                        }
                        ++index;
                    }
                    if (string.IsNullOrEmpty(className))
                    {
                        ProgressBar.HideBarWithFailInfo("\n空的类名(excel页签名), 路径:  " + inputPath);
                        throw new Exception("空的类名(excel页签名), 路径:  " + inputPath);
                    }
                    if (names != null && types != null)
                    {
                        //根据刚才的数据来生成C#脚本
                        ScriptGenerator generator = new ScriptGenerator(inputPath, className, names, types);
                        //所有生成的类的代码最终保存在这个链表中
                        codeList.Add(generator.Generate());
                        if (dataDict.ContainsKey(className))
                        {
                            ProgressBar.HideBarWithFailInfo("\n类名重复:" + className + " ,路径: " + inputPath);
                            throw new Exception("类名重复: " + className + " ,路径:  " + inputPath);
                        }
                        else dataDict.Add(className, dataList);
                    }
                }
                while (excelReader.NextResult());//excelReader.NextResult() Excel表下一个sheet页有没有数据
            }
            stream.Dispose();
            stream.Close();
        }

        //编译代码
        private static Assembly CompileCode(string[] scripts)
        {
            string path = System.Environment.CurrentDirectory + "/Assets/Plugins/" + CODE_NAMESPACE;
            if (Directory.Exists(path)) Directory.Delete(path, true);//删除旧dll
            Directory.CreateDirectory(path);
            //编译器实例对象
            CSharpCodeProvider codeProvider = new CSharpCodeProvider();
            //编译器参数实例对象
            CompilerParameters objCompilerParameters = new CompilerParameters();
            objCompilerParameters.ReferencedAssemblies.AddRange(new string[] { "System.dll" });//添加程序集引用
            objCompilerParameters.OutputAssembly = path + "/" + CODE_NAMESPACE + ".dll";//设置输出的程序集名
            objCompilerParameters.GenerateExecutable = false;
            objCompilerParameters.GenerateInMemory = true;

            //开始编译脚本
            CompilerResults cr = codeProvider.CompileAssemblyFromSource(objCompilerParameters, scripts);
            if (cr.Errors.HasErrors)
            {
                ProgressBar.HideBarWithFailInfo("\n编译dll出错(详情见控制台)!");
                foreach (CompilerError err in cr.Errors)
                {
                    Debug.LogError(err.ErrorText);
                }
                throw new Exception("编译dll出错!");
            }
            Debug.Log("已生成 " + path + "/" + CODE_NAMESPACE + ".dll");
            return cr.CompiledAssembly;
        }

        //序列化对象
        private static void Serialize(object container, Type temp, List dataList,string BinDataPath)
        {
            //设置数据
            foreach (ConfigData[] datas in dataList)
            {
                //Type.FullName 获取该类型的完全限定名称,包括其命名空间,但不包括程序集。
                object t = temp.Assembly.CreateInstance(temp.FullName);
                foreach (ConfigData data in datas)
                {
                    //Type.GetField(String) 搜索Type内指定名称的公共字段。
                    FieldInfo info = temp.GetField(data.Name);
                    // FieldInfo.SetValue 设置对象内指定名称的字段的值
                    info.SetValue(t, ParseValue(data.Type, data.Data, temp.Name));
                }
                // FieldInfo.GetValue 获取对象内指定名称的字段的值
                object id = temp.GetField("id").GetValue(t);//获取id
                FieldInfo dictInfo = container.GetType().GetField("Dict");
                object dict = dictInfo.GetValue(container);

                bool isExist = (bool)dict.GetType().GetMethod("ContainsKey").Invoke(dict, new System.Object[] { id });
                if (isExist)
                {
                    EditorUtility.DisplayDialog("注意!!!", "ID重复:" + id + ",类型: " + container.GetType().Name, "确定");
                    throw new Exception("ID重复:" + id + ",类型: " + container.GetType().Name);
                }
                dict.GetType().GetMethod("Add").Invoke(dict, new System.Object[] { id, t });
            }
            IFormatter f = new BinaryFormatter();
            Stream s = new FileStream(BinDataPath + "/" + container.GetType().Name + ".bytes", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write);
            f.Serialize(s, container);
            Debug.Log("已生成 " + BinDataPath + "/" + container.GetType().Name + ".bytes");
            s.Close();
        }

        public static object ParseValue(string type, string data, string classname)
        {
            object o = null;
            try
            {
                switch (type)
                {
                    case SupportType.INT:
                        o = int.Parse(data);
                        break;
                    case SupportType.LONG:
                        o = long.Parse(data);
                        break;
                    case SupportType.FLOAT:
                        o = float.Parse(data);
                        break;
                    case SupportType.STRING:
                        o = data;
                        break;
                    case SupportType.LIST_INT:
                        data = data.Substring(1, data.Length - 2);//移除 '['   ']'
                        string[] ints = data.Split(',');//逗号分隔
                        List list = new List();
                        foreach (var item in ints)
                        {
                            list.Add(int.Parse(item));
                        }
                        o = list;
                        break;
                    case SupportType.LIST_FLOAT:
                        data = data.Substring(1, data.Length - 2);//移除 '['   ']'
                        string[] floats = data.Split(',');//逗号分隔
                        List list2 = new List();
                        foreach (var item in floats)
                        {
                            list2.Add(float.Parse(item));
                        }
                        o = list2;
                        break;
                    case SupportType.LIST_STRING:
                        data = data.Substring(1, data.Length - 2);//移除 '['   ']'
                        string[] strs = data.Split(',');//逗号分隔
                        o = strs;
                        break;
                    case SupportType.LIST_LIST_INT:
                        break;
                    case SupportType.LIST_LIST_FLOAT:
                        break;
                    case SupportType.LIST_LIST_STRING:
                        break;
                    case SupportType.DICTIONARY_INT_INT:
                        break;
                    case SupportType.DICTIONARY_INT_FLOAT:
                        break;
                    case SupportType.DICTIONARY_INT_STRING:
                        break;
                    case SupportType.DICTIONARY_INT_LIST_INT:
                        break;
                    case SupportType.DICTIONARY_INT_LIST_FLOAT:
                        break;
                }
            }
            catch (Exception ex)
            {
                ProgressBar.HideBarWithFailInfo("\n" + "错误的数据值:" + data + "\n位于:" + classname);
                throw new Exception("\n错误的数据值:" + data + "\n位于:" + classname, ex);
            }
            return o;
        }
    }
}

脚本生成器 

using System.Collections.Generic;
using System.Collections;
using System.Text;
using System;
using UnityEngine;
using System.IO;
using System.Reflection;

namespace WJExcelDataManager
{
    public class SupportType
    {
        public const string INT = "i";
        public const string LONG = "l";
        public const string FLOAT = "f";
        public const string STRING = "s";
        public const string LIST_INT = "ai";
        public const string LIST_FLOAT = "af";
        public const string LIST_STRING = "as";
        public const string LIST_LIST_INT = "aai";
        public const string LIST_LIST_FLOAT = "aaf";
        public const string LIST_LIST_STRING = "aas";
        public const string DICTIONARY_INT_INT = "i_i";
        public const string DICTIONARY_INT_FLOAT = "i_f";
        public const string DICTIONARY_INT_STRING = "i_s";
        public const string DICTIONARY_INT_LIST_INT = "i_ai";
        public const string DICTIONARY_INT_LIST_FLOAT = "i_af";
    }
    //脚本生成器
    public class ScriptGenerator
    {
        private string[] Names;
        private string[] Types;
        private string ClassName;
        private string InputPath;

        public ScriptGenerator(string inputPath, string className, string[] fileds, string[] types)
        {
            InputPath = inputPath;
            ClassName = className;
            Names = fileds;
            Types = types;
        }

        //开始生成脚本
        public string Generate()
        {
            if (Types == null || Names == null || ClassName == null)
                throw new Exception("表名:" + ClassName + 
                                    "\n表名为空:" + (ClassName == null) + 
                                    "\n字段类型为空:" + (Types == null) + 
                                    "\n字段名为空:" + (Names == null));
            return CreateCode(ClassName, Types, Names);
        }

        //创建代码。   
        private string CreateCode(string ClassName, string[] types, string[] fields)
        {
            //生成类
            StringBuilder classSource = new StringBuilder();
            classSource.Append("/*Auto create\n");
            classSource.Append("Don't Edit it*/\n");
            classSource.Append("\n");
            classSource.Append("using System;\n");
            classSource.Append("using System.Reflection;\n");
            classSource.Append("using System.Collections.Generic;\n");
            classSource.Append("namespace " + ExcelDataTool.CODE_NAMESPACE + "\n");
            classSource.Append("{\n");
            classSource.Append("[Serializable]\n");
            classSource.Append("public class " + ClassName + "Item\n");//表里每一条数据的类型名为表类型名加Item
            classSource.Append("{\n");
            //设置成员
            for (int i = 0; i < fields.Length; ++i)
            {
                classSource.Append(PropertyString(types[i], fields[i]));
            }
            classSource.Append("}\n");

            //生成Container
            classSource.Append("\n");
            classSource.Append("[Serializable]\n");
            classSource.Append("public class " + ClassName + "\n");
            classSource.Append("{\n");
            string idType = "";
            for (int i = 0; i < fields.Length; i++)
            {
                if (fields[i] == "id" || fields[i] == "ID" || fields[i] == "iD" || fields[i] == "Id")
                {
                    idType = GetTrueType(types[i]);
                    break;
                }
            }
            classSource.Append("\tpublic " + "Dictionary<" + idType + ", " + ClassName + "Item" + " > " + " Dict" + " = new Dictionary<" + idType + ", " + ClassName + "Item" + ">();\n");
            classSource.Append("}\n");
            classSource.Append("}\n");
            return classSource.ToString();
            /*  //生成的条目数据类
                namespace WJExcelDataClass
                {
                    public class testItem
                    {
                        public int id;
                        public float m_float;
                        public string str;
                        public test();
                    }
                }

                //生成的表数据类
                using System.Collections.Generic;
                namespace WJExcelDataClass
                {
                    public class test
                    {
                        public Dictionary Dict;
                        public testContainer();
                    }
                }
             */
        }

        private string PropertyString(string type, string propertyName)
        {
            if (string.IsNullOrEmpty(type) || string.IsNullOrEmpty(propertyName))
                return null;

            type = GetTrueType(type);
            if (!string.IsNullOrEmpty(type))
            {
                StringBuilder sbProperty = new StringBuilder();
                sbProperty.Append("\tpublic " + type + " " + propertyName + ";\n");
                return sbProperty.ToString();
            }
            else
            {
                return "";
            }
        }

        private string GetTrueType(string type)
        {
            switch (type)
            {
                case SupportType.INT:
                    type = "int";
                    break;
                case SupportType.LONG:
                    type = "long";
                    break;
                case SupportType.FLOAT:
                    type = "float";
                    break;
                case SupportType.STRING:
                    type = "string";
                    break;
                case SupportType.LIST_INT:
                    type = "List";
                    break;
                case SupportType.LIST_FLOAT:
                    type = "List";
                    break;
                case SupportType.LIST_STRING:
                    type = "List";
                    break;
                case SupportType.LIST_LIST_INT:
                    break;
                case SupportType.LIST_LIST_FLOAT:
                    break;
                case SupportType.LIST_LIST_STRING:
                    break;
                case SupportType.DICTIONARY_INT_INT:
                    break;
                case SupportType.DICTIONARY_INT_FLOAT:
                    break;
                case SupportType.DICTIONARY_INT_STRING:
                    break;
                case SupportType.DICTIONARY_INT_LIST_INT:
                    break;
                case SupportType.DICTIONARY_INT_LIST_FLOAT:
                    break;
                default:
                    ProgressBar.HideBarWithFailInfo("\n输入了错误的数据类型: " + type + ", 类名: " + ClassName + ", 位于: " + InputPath);
                    throw new Exception("输入了错误的数据类型:  " + type + ", 类名:  " + ClassName + ", 位于:  " + InputPath);
            }
            return type;
        }

        //创建数据管理器脚本
        public static void CreateDataManager(Assembly assembly)
        {
            List list = new List();
            list.AddRange(assembly.GetTypes());
            IEnumerable types = list.FindAll(t => { return !t.Name.Contains("Item"); });

            StringBuilder source = new StringBuilder();
            source.Append("/*\n");
            source.Append(" *   This file was generated by a tool.\n");
            source.Append(" *   Do not edit it, otherwise the changes will be overwritten.\n");
            source.Append(" */\n");
            source.Append("\n");

            source.Append("using System;\n");
            source.Append("using UnityEngine;\n");
            source.Append("using System.Runtime.Serialization;\n");
            source.Append("using System.Runtime.Serialization.Formatters.Binary;\n");
            source.Append("using System.IO;\n");
            source.Append("using " + ExcelDataTool.CODE_NAMESPACE + ";\n\n");
            source.Append("[Serializable]\n");
            source.Append("public class DataManager //: SingletonTemplate\n");
            source.Append("{\n");

            //定义变量
            foreach (Type t in types)
            {
                source.Append("\tpublic " + t.Name + " p_" + t.Name + ";\n");
            }
            source.Append("\n");

            //定义方法
            foreach (Type t in types)
            {
                string typeName = t.Name + "Item";//类型名
                string funcName = typeName.Remove(1).ToUpper() + typeName.Substring(1);//将类型名第一个字母大写
                List fields = new List();
                fields.AddRange(list.Find(temp => temp.Name == typeName).GetFields());//获取数据类的所有字段信息
                string idType = fields.Find(f => f.Name == "id" || f.Name == "ID" || f.Name == "iD" || f.Name == "Id").FieldType.Name;//获取id的数据类型
                source.Append("\tpublic " + typeName + " Get" + funcName + "ByID" + "(" + idType + " id)\n");
                source.Append("\t{\n");
                source.Append("\t\t" + typeName + " t = null;\n");
                source.Append("\t\tp_" + t.Name + ".Dict.TryGetValue(id, out t);\n");
                source.Append("\t\tif (t == null) Debug.LogError(" + '"' + "can't find the id " + '"' + " + id " + "+ " + '"' + " in " + t.Name + '"' + ");\n");
                source.Append("\t\treturn t;\n");
                source.Append("\t}\n\n");
            }

            加载所有配置表
            source.Append("\tpublic void LoadAll()\n");
            source.Append("\t{\n");
            foreach (Type t in types)
            {
                source.Append("\t\tp_" + t.Name + " = Load(" + '"' + t.Name + '"' + ") as " + t.Name + ";\n");
            }
            source.Append("\t}\n\n");

            //反序列化
            source.Append("\tprivate System.Object Load(string name)\n");
            source.Append("\t{\n");
            source.Append("\t\tIFormatter f = new BinaryFormatter();\n");
            source.Append("\t\tTextAsset text = Resources.Load(" + '"' + ExcelDataTool.BinDataFolder + "/" + '"' + " + name);\n");
            source.Append("\t\tStream s = new MemoryStream(text.bytes);\n");
            source.Append("\t\tSystem.Object obj = f.Deserialize(s);\n");
            source.Append("\t\ts.Close();\n");
            source.Append("\t\treturn obj;\n");
            source.Append("\t}\n");
            source.Append("}\n");

            //保存脚本
            string path = System.Environment.CurrentDirectory + "/Assets/Scripts/ExcelDataManager";
            if (!Directory.Exists(path)) Directory.CreateDirectory(path);
            StreamWriter sw = new StreamWriter(path + "/DataManager.cs");
            sw.WriteLine(source.ToString());
            Debug.Log("已生成 " + path + "/DataManager.cs");
            sw.Close();

            /*  //生成的数据管理类如下
                using System;
                using UnityEngine;
                using System.Runtime.Serialization;
                using System.Runtime.Serialization.Formatters.Binary;
                using System.IO;
                using ExcelConfigClass;
                [Serializable]
                public class DataManager //: SingletonTemplate
                {
	                public test p_test;
	                public test2 p_test2;

	                public testItem GetTestItemByID(Int32 id)
	                {
		                testItem t = null;
		                p_test.Dict.TryGetValue(id, out t);
		                if (t == null) Debug.LogError("can't find the id " + id + " in test");
		                return t;
	                }

	                public test2Item GetTest2ItemByID(String id)
	                {
		                test2Item t = null;
		                p_test2.Dict.TryGetValue(id, out t);
		                if (t == null) Debug.LogError("can't find the id " + id + " in test2");
		                return t;
	                }

	                public void LoadAll()
	                {
		                p_test = Load("test") as test;
		                p_test2 = Load("test2") as test2;
	                }

	                private System.Object Load(string name)
	                {
		                IFormatter f = new BinaryFormatter();
		                TextAsset text = Resources.Load("BinConfigData/" + name);
		                Stream s = new MemoryStream(text.bytes);
		                System.Object obj = f.Deserialize(s);
		                s.Close();
		                return obj;
	                }
                }
            */

        }
    }
}


 导表路径

using UnityEngine;
using UnityEditor;

namespace WJExcelDataManager
{
    public class PathWindow : EditorWindow
    {
        static EditorWindow window;
        [MenuItem("开发工具/导表工具/设置导表路径")]
        public static void Init()
        {
            window = EditorWindow.GetWindow(typeof(PathWindow));
            window.titleContent.text = "设置路径";
            window.ShowTab();
            window.Show();
        }
        private string m_Path;
        void OnGUI()
        {
            EditorGUILayout.LabelField("", GUILayout.MaxHeight(5f));
            EditorGUILayout.LabelField("当前路径", GUILayout.MinHeight(20f));
            EditorGUILayout.LabelField(PlayerPrefs.GetString(System.Environment.CurrentDirectory + "ExcelDataInputPath", ""), GUILayout.MinHeight(20f));
            if (GUILayout.Button("选择路径"))
            {
                string oldpath = PlayerPrefs.GetString(System.Environment.CurrentDirectory + "ExcelDataInputPath", "");
                string path = EditorUtility.OpenFolderPanel("设置导表路径", oldpath, "");//打开文件夹选择面板
                if (!string.IsNullOrEmpty(path))
                {
                    PlayerPrefs.SetString(System.Environment.CurrentDirectory + "ExcelDataInputPath", path);
                    Debug.Log("新的excel文件路径: " + "" + path + "");
                    EditorUtility.DisplayDialog("Set Excel Data Input Path", "\n新的excel文件路径:  " + path, "OK");
                    window.Repaint();
                }
            }
        }
    }
}

进度条

using UnityEditor;

namespace WJExcelDataManager
{
    public class ProgressBar : EditorWindow
    {
        void OnInspectorUpdate() //更新
        {
            Repaint();  //重新绘制
        }

        public static void UpdataBar(string info, float progress)
        {
            //使用这句代码,在进度条后边会有一个 关闭按钮,但是用这句话会直接卡死,切记不要用
            //EditorUtility.DisplayCancelableProgressBar("Loading Excel Data", info + "...", progress);
            //使用这句创建一个进度条,  参数1 为标题,参数2为提示,参数3为 进度百分比 0~1 之间
            EditorUtility.DisplayProgressBar("导表工具", info + "...", progress);
            if (progress >= 1)
            {
                EditorUtility.ClearProgressBar();
                EditorUtility.DisplayDialog("导表工具", info, "确定");
            }
        }
        public static void HideBarWithFailInfo(string failinfo)
        {
            EditorUtility.ClearProgressBar();
            EditorUtility.DisplayDialog("注意!!!", failinfo, "确定");
        }
    }
}

使用ExcelDataReader读写excel(.xls,.xlsx)

https://blog.csdn.net/chen_victor/article/details/70140925

源代码:unity导表工具-CSDN下载  https://download.csdn.net/download/oldherowang/10653750

 

你可能感兴趣的:(unity3d,C#)