【Unity】解析Excel数据,并自动创建对应的C#类
升级版传送门:
【Unity】升级版·Excel数据解析,自动创建对应C#类,自动创建ScriptableObject生成类,自动序列化Asset文件_萧然CS的博客-CSDN博客Excel注释操作:行数据类,对应每一行数据:完整数据类,包含所有行的数据、初始化函数、Get函数:目前支持的数据结构:字符串testString字符串数组testStringArray字符串二维数组testStringArray2InttestIntInt数组testIntArrayInt二维数组testIntArray2FloattestFlohttps://z-c-s.blog.csdn.net/article/details/125608062
参考:Unity C#配置表工具
解析流程:
1. 配置Excel
2. 读取解析Excel (引用Excel.dll, ICSharpCode.SharpZipLib.dll)
3. 重新整理解析到的数据
4. 创建Excel对应的C#类,声明变量
5. 在类的构建函数中给变量赋值
6. 保存类文件,可在游戏直接使用
优点:
1. 每个Excel对应一个类,使用灵活,对Excel限制少
2. 自动创建脚本,不需要对每个Excel手动写代码
3. 数据值直接写到脚本里,方便查看,可以手动修改调整,不需要每次改动都在Excel里操作
4. 在游戏内直接调用类,不需要额外操作
缺点:
1. 表格格式确定后不能轻易修改,改动可能影响类的结构,代码报错
2. 因为是把数据直接写入到脚本内,数据量较大时可能会有问题
具体流程:
1. 配置Excel
格式:
预留前两行,可以写一些备注;第三行为数据格式;第四行为变量名字,第五行以后是数据内容
第一列为id,后面每一列为一个变量
Sheet页的名字,是创建类的类名
2. 解析Excel
3. 整理数据
解析Excel时,是按照行顺序,一行一行解析的,将每行数据记录下来,方式有很多,能满足使用要求即可
//注释说明
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using Excel;
using System.Reflection;
using System;
using System.Text;
using System.Linq;public class ExcelReader
{const int excelTypeRow = 3;const int excelNameRow = 4;static string excelFilePath = Application.dataPath + "/Excel";static string excelCodePath = Application.dataPath + "/Script/Excel/AutoCreate";public static void Read(){//读取所有Excel文件string[] excelFiles = Directory.GetFiles(excelFilePath, "*.xlsx");if (excelFiles.Length == 0){Debug.Log("Excel file count == 0");return;}//代码类List<KeyValuePair<string, string>> codeList = new List<KeyValuePair<string, string>>();//遍历所有Excelfor (int i = 0; i < excelFiles.Length; i++){//打开Excelstring excelFile = excelFiles[i];FileStream stream = File.Open(excelFile, FileMode.Open, FileAccess.Read);//解析ExcelIExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);if (!excelReader.IsValid){Debug.Log("Invalid excel : " + excelFile);continue;}string[] propertyTypes = null;string[] propertyNames = null;List<List<KeyValuePair<string, string>>> allItemRowList = new List<List<KeyValuePair<string, string>>>();int rowIndex = 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])){rowIndex++;continue;}if (rowIndex == excelTypeRow){//行数据表示类型propertyTypes = datas;}else if (rowIndex == excelNameRow){//行数据表示变量名propertyNames = datas;}else if (rowIndex > excelNameRow){//行数据表示变量值List<KeyValuePair<string, string>> itemList = new List<KeyValuePair<string, string>>();//遍历一行里的每个数据//for (int j = 0; j < datas.Length; ++j)//{// if (j >= names.Length)// continue;// //读取数据// itemList.Add(new KeyValuePair<string, string>(names[j], datas[j]));//}for (int j = 0; j < propertyNames.Length; j++){if (j < datas.Length)itemList.Add(new KeyValuePair<string, string>(propertyNames[j], datas[j]));elseitemList.Add(new KeyValuePair<string, string>(propertyNames[j], null));}allItemRowList.Add(itemList);}rowIndex++;}if (propertyNames == null || propertyNames.Length == 0|| propertyTypes == null || propertyTypes.Length == 0|| propertyNames.Length != propertyTypes.Length)continue;//变量对应的所有值Dictionary<string, List<string>> propertyValueDic = new Dictionary<string, List<string>>();for (int k = 0; k < propertyNames.Length; k++){propertyValueDic.Add(propertyNames[k], new List<string>());}for (int m = 0; m < allItemRowList.Count; m++){for (int n = 0; n < allItemRowList[m].Count; n++){propertyValueDic[allItemRowList[m][n].Key].Add(allItemRowList[m][n].Value);}}//类名string className = excelReader.Name + "Table";//根据数据生成C#脚本ScriptGenerator generator = new ScriptGenerator(className, propertyNames, propertyTypes, propertyValueDic);string codeStr = generator.CreateCode();//生成的类codeList.Add(new KeyValuePair<string, string>(className, codeStr));}if (!Directory.Exists(excelCodePath))Directory.CreateDirectory(excelCodePath);for (int i = 0; i < codeList.Count; i++){string className = codeList[i].Key;string codeStr = codeList[i].Value;StreamWriter sw = new StreamWriter(excelCodePath + "/" + className + ".cs");sw.WriteLine(codeStr);sw.Close();}UnityEditor.AssetDatabase.Refresh();Debug.Log("<color=green>Auto Scripts Success : </color>" + codeList.Count);}
}
4. 创建C#类
5. 变量赋值
创建脚本,这里采用拼接字符串的方式,变量赋值也是拼接的字符串,然后将拼接好的文本保存为".cs"文件
在参考链接中是生成dll文件,这种方式感觉高级一些
方法有很多,不局限于这两种,能实现功能就好
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
using System;public class ScriptGenerator
{
//脚本生成器string className;string[] propertyNames;string[] propertyTypes;Dictionary<string, List<string>> propertyValueDic;public ScriptGenerator(string tableName, string[] names, string[] types, Dictionary<string, List<string>> valueDic){className = tableName;propertyNames = names;propertyTypes = types;propertyValueDic = valueDic;}//创建代码public string CreateCode(){//生成类StringBuilder classSource = new StringBuilder();classSource.Append("/*Auto create, 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("\n");classSource.Append("[Serializable]\n");classSource.Append("public class " + className + " : TableBase\n");classSource.Append("{\n");//声明变量for (int i = 0; i < propertyNames.Length; i++){classSource.Append(PropertyString(propertyNames[i], propertyTypes[i]));}//构造函数内赋值classSource.Append("\n");classSource.Append("\tpublic " + className + "()\n");classSource.Append("\t{\n");for (int i = 0; i < propertyNames.Length; i++){classSource.Append(Assignment(propertyNames[i], propertyTypes[i], propertyValueDic[propertyNames[i]]));}classSource.Append("\t}\n");//Get方法classSource.Append("\n");classSource.Append("\tint targetIndex;\n");classSource.Append("\n");for (int i = 0; i < propertyNames.Length; i++){if (propertyNames[i] == "id")continue;classSource.Append("\tpublic " + propertyTypes[i] + " Get" + propertyNames[i].ToUpper() + "(string targetId)\n");classSource.Append("\t{\n");classSource.Append("\t\ttargetIndex = id.IndexOf(targetId);\n");classSource.Append("\t\tif (targetIndex < 0)\n");classSource.Append("\t\t\treturn default;\n");classSource.Append("\t\treturn " + propertyNames[i] + "[targetIndex];\n");classSource.Append("\t}\n");}//classSource.Append("}\n");return classSource.ToString();}private string PropertyString(string name, string type){if (string.IsNullOrEmpty(name))return null;if (type == "int")type = "List<int>";else if (type == "float")type = "List<float>";elsetype = "List<string>";string propertyStr = "\tpublic " + type + " " + name + ";\n";return propertyStr;}private string Assignment(string name, string type, List<string> valueList){StringBuilder source = new StringBuilder();source.Append("\t\t" + name + " = new List<" + type + ">()\n");source.Append("\t\t{\n");source.Append("\t\t\t");Func<string, string> CheckPropertyAct;if (type == "int")CheckPropertyAct = CheckPropertyInt;else if (type == "float")CheckPropertyAct = CheckPropertyFloat;elseCheckPropertyAct = CheckPropertyString;for (int i = 0; i < valueList.Count; i++){source.Append(CheckPropertyAct(valueList[i]) + ", ");}source.Append("\n");source.Append("\t\t};\n");return source.ToString();}private string CheckPropertyInt(string value){return Convert.ToInt32(value).ToString();}private string CheckPropertyFloat(string value){return Convert.ToSingle(value) + "f";}private string CheckPropertyString(string value){return "\"" + value + "\"";}}
6. 把脚本文本保存为".cs"文件,在游戏里就可以直接使用咯~
-------------------- 分割线 --------------------
理论改良版:
1. 还是将Excel转为对应的C#类,不过只创建数据List(或者Dictionary),不赋值,即不保存数据,只记录数据类型
2. 将Excel数据用txt、json或byte二进制保存到本地(json的话可以对应类的格式)
3. 读取数据时初始化对应的类,获取Excel数据进行赋值
-------------------- 分割线 --------------------
改良进阶版:
【Unity】解析Excel数据,自动创建对应的C#类,创建ScriptableObject的Asset文件并赋值
【Unity】解析Excel数据,自动创建对应的C#类,创建ScriptableObject的Asset文件并赋值_萧然-CSDN博客
【Unity】解析Excel数据,并自动创建对应的C#类相关推荐
- Excel VBA 宏自动创建表格
Excel VBA 宏 - 自动创建表格 应朋友的需求,编写了一个 VBA 宏,用于自动创建工作簿,实现了排版布局.冻结表头.条件格式.自动求和.单元格保护等功能. 分别创建了 4 个工作簿 1-12 ...
- 利用js-xlsx.js插件实现Excel文件导入并解析Excel数据成json数据格式
<!--本文转载于网络,有太多一样的文章,不知道原作者是哪位了,就不注明出处了.这里记载下来,用于自己的学习借鉴--><!DOCTYPE html><html lang= ...
- Java读取和解析Excel数据:基于Apache POI(二)
Java读取和解析Excel数据:基于Apache POI(二) 假设附录1文章中的test.xls是对员工的考勤记录表.需要根据这张excel表统计员工的加班时间,那么需要重点关注第五列的下班时候的 ...
- unity解析json 数据
1.使用JsonUtility解析 JsonUtility是unity自带的解析json的工具. 1.1具体使用创建一个解释数据的对象类 需要注意的是需要将每一个方法序列化,使用[System.Ser ...
- unity读取excel数据并绘制曲线
一.读取数据 1.导入EPPlus类库:EPPlus.dll 2.创建script脚本 3.创建空物体,挂载脚本 using System.Collections; using System.Coll ...
- Unity 解析视频流数据
首先在AndroidStudio中将数据转换为yuv图片数据,然后传到Unity,Unity解析Yuv图片数据并显示 MediaCodec mCodec = MediaCodec.createDeco ...
- poi读取excel 转换实体_java解析excel数据,将excel数据转换为实体类,存入数据库...
前一段时间写了一个功能,从数据库中抽取出来的字段,写入到excel文件里:java使用poi把从数据库中取出的数据写入excel 最近实现了一个相反的功能,前台传一个excel文件,在后台解析该exc ...
- java解析excel存入map,java解析excel数据,将excel数据转换为实体类,存入数据库
前一段时间写了一个功能,从数据库中抽取出来的字段,写入到excel文件里:java使用poi把从数据库中取出的数据写入excel 最近实现了一个相反的功能,前台传一个excel文件,在后台解析该exc ...
- python绘制动态图表怎么存下来_用python如何实现导入excel数据后自动生成图表?python如何实现交互式动态图表?...
这个需求涉及的环节太多了.导入excel文件,获取数据 -- 需要xlrd模块把数据导入python 2. 设定输出图表类型 -- 需要matplot模块.根据数据复杂度,可能需要ETL,那么需要pa ...
最新文章
- 【CURL】模拟登录网站并获取用户信息
- springboot定时执行任务
- T2821 天使之城 codevs
- Python的open函数文件读写线程不安全,logging模型文件读写线程安全!
- vsftpd配置文件丢失
- C语言的main函数,究竟有几种写法?
- 进程的创建与可执行程序的加载
- 牛客 21302 被3整除的子序列 (动态规划、Python)
- STM32H743+CubeMX-梳理MPU的设置
- [深度学习] tensorflow1.x和tensorflow2.x对比与总结
- 搭建属于自己的私有链,部署简单的智能合约
- 互不相识的人在什么情况下会给你点赞呢?
- frida-trace入门
- 【表格】从1G到5G的移动通信发展历程(精简版)
- windows虚拟机共享windows主机文件
- 阿里云Centos7修改22默认端口
- 什么是路由器 它的工作原理是什么
- matlab能画五维吗,进化算法之粒子群算法和Matlab实现(多维)
- 两平面平行但不重合的条件是_____黑龙江省大庆外国语学校高中数学_第二章《2.2_直线、平面平行的判定及其性质》单元测试5_新人教A版必修3...
- Linux下php重启的问题