ConfigExcel 是一款基于 C# 代码热更新方案(如 ILRuntime / HybridCLR)设计的工具。它能够自动将 Excel 表格数据转换为 C# 类代码并直接填充数据,从而避免了运行时的序列化和反序列化开销。生成的代码为标准 C# 代码,可无缝应用于 PC、安卓、iOS、微信小游戏等多种平台。
- 零GC、零IO开销:生成的代码在访问数据时无需进行文件读取或复杂的反序列化操作。
- 懒加载:数据在首次访问时才加载,优化启动性能和内存占用。
- 易于上手:无需学习新的数据格式或配置方式,直接使用 Excel 进行数据管理。
- 跨平台兼容:生成的 C# 代码具有良好的跨平台特性。
- 热更新友好:生成的C#代码可以直接集成到热更新的DLL中,方便数据和代码的同步更新。
对于在 Unity 项目中使用此工具的开发者,我们推荐直接在编辑器内集成和使用,这样可以更便捷地管理和生成代码。
此方法允许您直接在 Unity 编辑器中从 Excel 文件生成 C# 代码,无需使用独立的 Excel2Code.exe 程序。
- 将
UnityDemo/Assets/Editor/AutoExcel/目录下的以下文件复制到您 Unity 项目的Assets/Editor/文件夹下的任意子目录中:ConfigExcel.csExcel2Code.csUtils.cs
- 将
UnityDemo/Assets/Editor/AutoExcel/EPPlus.dll文件复制到您的 Unity 项目中 (例如,放到Assets/Plugins/或Assets/Editor/下的某个目录)。这是在 Unity 环境下解析 Excel 文件所需的库。
完成上述设置后,Unity 编辑器顶部菜单栏会出现 "Tools > ConfigExcel" 选项。点击该菜单项会打开一个窗口,您可以在其中指定包含 Excel 文件的输入目录、C# 代码的输出目录以及需要忽略的文件列表(逗号分隔,无需扩展名)。点击 "导出Excel" 按钮即可开始生成代码。
- Excel 解析库 (Excel Parsing Library): Unity 版本使用
EPPlus.dll,而独立版使用 NPOI。因此,EPPlus.dll是 Unity 集成所必需的。 - 无代码编译 (No Code Compilation): 此集成脚本不包含编译生成后 C# 代码的功能。您需要依赖 Unity自身的编译流程。
- 无历史记录/增量生成 (No History/Incremental Generation): Unity 版本不使用
history.txt,每次都会重新生成所有指定文件。 - Sheet 命名规则差异 (Sheet Naming Rule Differences):
- 不支持
|作为 Sheet 名称中的分隔符 (仅支持空格)。 - 不支持以
=开头的 Sheet 用于扩展数据。 - Unity 版本目前不会显式忽略名为
Sheet1,Sheet2等的默认工作表,但如果它们不符合其他解析规则,也可能不会被处理。
- 不支持
- 类型替换差异 (
drepalace): Unity 版本中可用的类型替换较少 (例如,不支持dic,v2[],v3[],luatable,luacode的直接替换)。 - 自定义数据类处理 (Custom Data Class Handling): 如果您在 Excel 中定义了需要工具实例化的自定义类 (例如,类型列填写为
MyData),该类在 Unity 版本中需要有一个public void FromString(string excelData)方法来从 Excel单元格的字符串内容初始化自身。例如:public class MyData { public void FromString(string excelData) { /* 解析 excelData 并填充字段 */ } }。 - 命名空间 (Namespace): Unity 版本生成的 C# 代码不包含外层命名空间 (例如
namespace ConfigExcel {...}被移除)。 - 输出信息 (Output Messages): 使用
UnityEngine.Debug.Log输出日志。
注意: 以下描述的许多功能和规则主要基于独立版 Excel2Code.exe。Unity 编辑器集成版本在某些方面(如Sheet命名、部分类型支持、无编译步骤等)存在差异。具体差异请参考“推荐使用方法:在 Unity 编辑器中使用”部分下的“与独立版 (.exe) 的主要区别”表格。核心的数据转换逻辑是相似的。
- 导出目录中的所有 Excel 文件:
Excel2Code.exe -dir Excels
- 导出指定的 Excel 文件:
Excel2Code.exe Excels/test.xlsx Excels/test2.xlsx
-
以
#开头的 Sheet (基础类型集合):- Sheet 名称以
#开头的表格,会被识别为基础类型集合。 - 表格结构:第一列为数据类型,第二列为变量名,第三列为具体内容。
- 当内容为
int/string/bool类型时,第一列(数据类型)可以为空,工具会自动推断类型。
- Sheet 名称以
-
不以
#开头的 Sheet (数据表):- Sheet 名称不以
#开头的表格,会被识别为数据表。 - 表格结构:第一行为注释,第二行为变量名,第三行为数据类型。
- Sheet 名称不以
-
Sheet 名为 "类名 变量名" 或 "模块名 类名 变量名" 格式:
- 当 Sheet 名的格式为两段式“NameOne NameTwo”(或使用
|分隔:“NameOne | NameTwo”)时,NameTwo会被作为类名,NameOne通常代表模块或分类,解析后的变量名为mNameTwo(单个实例) /dNameTwo(字典) /lNameTwo(列表)。 - 当 Sheet 名的格式为三段式“NameOne NameTwo NameThree”(或使用
|分隔:“NameOne | NameTwo | NameThree”)时,NameThreeData会被作为类名,NameOne和NameTwo通常代表模块或分类,解析后的变量名为mNameThreeData/dNameThreeData/lNameThreeData。 - 成员变量: 当表格除去表头(注释、变量名、数据类型行)后只有一行有效数据时,该 Sheet 会被识别为类的单个成员变量。
- 类字典: 如果表格中有多行数据,该 Sheet 会被识别为该类的字典,键的类型由第一列决定,值为类实例,即
Dictionary<第一列的数据类型, 类实例>。 - 类列表: 如果表格第一行(注释行)第一列中包含
list关键字,该 Sheet 会被识别为该类的列表,即List<类实例>。
- 当 Sheet 名的格式为两段式“NameOne NameTwo”(或使用
-
Sheet 名为单个词 (类名):
- 当 Sheet 名只有一个单词时(例如:"GlobalConfig"),该单词会被识别为类名。
- 这种情况下,生成的变量名会根据具体内容自动识别并添加前缀:
d类名(例如:dGlobalConfig),通常用于字典 (Dictionary<key, GlobalConfig>)。m类名(例如:mGlobalConfig),当代码生成为列表时 (例如List<GlobalConfig>),或作为单个实例对象时(后者通常源于如“成员变量”描述中所述的具有单行数据的Sheet),变量名均使用m前缀。
-
以
=开头的 Sheet (扩展数据表):- 这类 Sheet 用于扩展其前方最近一个主数据表(定义了字典的 Sheet)的数据。它们的内容会合并到主数据表的字典中。例如,如果
MyDataSheet定义了一个字典,并且其后紧跟着=SheetPart2和=SheetPart3,那么=SheetPart2和=SheetPart3中的数据将被添加到MyDataSheet的字典里。
- 这类 Sheet 用于扩展其前方最近一个主数据表(定义了字典的 Sheet)的数据。它们的内容会合并到主数据表的字典中。例如,如果
-
以
Sheet开头的 Sheet (忽略处理):- 以 Excel 默认命名模式
Sheet开头(例如Sheet1,Sheet2等)的 Sheet 将被忽略,不进行处理。
- 以 Excel 默认命名模式
- 支持各种 C# 基础数据类型 (如
int,string,bool,float等),需要确保 Excel 中填充的内容与声明的类型匹配。 - 支持基础类型的数组 (如
int[],string[]),同样需要确保填充内容合法。 - 支持 Key 和 Value 均为基础类型的字典 (如
Dictionary<int, string>),需要确保填充内容合法。 - 支持用户自定义的复杂类型,如果其名称以
Data开头或结尾(例如MyCustomData),或者使用特定的短语如v2,v3,v2[],v3[](这些会分别映射到DataVector2,DataVector3,DataVector2[],DataVector3[])。工具会尝试将单元格内容构造成new ClassName()或new ClassName[]{}的形式。用户需要确保这些自定义类在项目中已定义。 - 支持类型别名:在 Excel 中可使用
map或dic来代表Dictionary类型。同时,luatable和luacode也会被直接转换为string类型。例如,类型列中填写map<int,string>等同于Dictionary<int,string>。
- 请确保已安装 .NET 5.0 或更高版本。
- 需要将
EPPlus.dll添加到项目中(UnityDemo文件夹内已提供此文件)。 - 对 Unity 编辑器本身的版本无特殊要求,能够正常运行您的 Unity 项目即可。
除了在 Unity 编辑器中直接使用外,您也可以使用独立的 Excel2Code.exe 程序来生成代码。此独立版本拥有一些特有功能,例如通过 history.txt 实现的增量生成(自动跳过未更改的 Excel 文件以提高效率)、将生成的代码直接编译成 DLL,以及更全面的Sheet命名规则和类型别名支持。当您需要在 Unity 环境之外处理 Excel 文件,或者需要这些特定功能时,可以选用此方法。
您可以通过以下几种方式运行 Excel2Code.exe:
-
导出指定目录下的所有 Excel 文件: 打开命令行工具,执行以下命令(以
Excels作为存放 Excel 文件的目录为例):Excel2Code.exe -dir Excels -out ./GeneratedCode -compile ./GeneratedCode -ignore SecretTable,OldData
-dir <Excel目录>: 必需参数,指定包含 Excel 文件的目录。-out <输出目录>: 可选参数,指定生成的 C# 代码文件 (.cs) 的输出目录。如果未提供此参数,则不会生成代码文件。-compile <编译目录>: 可选参数,指定包含要编译的 C# 代码文件的目录(通常与-out目录相同)。如果提供此参数,工具会在代码生成后尝试将该目录中的所有.cs文件编译成一个临时的temp.dll。编译成功会提示,编译失败会显示错误。这个过程有助于快速验证生成的代码是否语法正确,并且为需要动态加载DLL的热更新方案提供了一种可能性。如果编译失败,会输出详细错误信息。当编译成功后,temp.dll会被自动删除,它主要用于即时验证。如果未提供此参数,则不执行编译步骤。-ignore <文件名列表>: 可选参数,提供一个逗号分隔的 Excel 文件名列表(无需扩展名),这些文件将被忽略处理。例如:-ignore SecretTable,OldData。
-
导出指定的若干个 Excel 文件: 打开命令行工具,执行以下命令,列出所有需要导出的文件路径。这种方式下,如果未指定
-out参数,生成的 C# 代码将默认输出到程序运行目录下的./exportcsharp文件夹中。Excel2Code.exe Excels/test.xlsx Excels/other1.xlsx Excels/other2.xlsx -out ./SpecificCode
同样可以配合使用
-compile参数 (如果-out未指定,-compile将作用于./exportcsharp目录)。-ignore参数仅在与-dir参数一同使用时生效。 -
通过交互模式导出: 直接双击
Excel2Code.exe文件,程序会提示您输入包含 Excel 文件的目录路径。
在 Excel2Code.exe 工具的执行目录下(通常在 bin/Debug/net5.0/ 或类似路径下),您可以找到:
- 示例 Excel 文件位于该执行目录下的
Excels/子目录内。这些示例覆盖了目前支持的各种配置写法。 - 生成的 C# 代码样例位于该执行目录下的
Codes/子目录内。 建议参考这些示例以深入了解具体用法和配置规则。这些示例主要演示了独立版Excel2Code.exe的配置方法。对于 Unity 版本,Excel 表格本身的结构和数据填写方式基本一致,但部分高级命名规则或类型支持可能存在差异,请务必参考“与独立版 (.exe) 的主要区别”部分的说明。
本项目采用 MIT 许可证。
欢迎参与贡献!您可以通过提交 Pull Request 或创建 Issue 的方式参与到项目中来。