ExcelCodeCreater.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System.Text;
  5. using System.Linq;
  6. using System;
  7. public class ExcelCodeCreater
  8. {
  9. //创建代码,生成数据C#类
  10. public static string CreateCodeStrByExcelData(ExcelMediumData excelMediumData)
  11. {
  12. if(excelMediumData == null)
  13. return null;
  14. //行数据类名
  15. string itemClassName = excelMediumData.excelName + "ExcelItem";
  16. //整体数据类名
  17. string dataClassName = excelMediumData.excelName + "ExcelData";
  18. //开始生成类
  19. StringBuilder classSource = new StringBuilder();
  20. classSource.AppendLine("/*Auto Create, Don't Edit !!!*/");
  21. classSource.AppendLine();
  22. //添加引用
  23. classSource.AppendLine("using UnityEngine;");
  24. classSource.AppendLine("using System.Collections.Generic;");
  25. classSource.AppendLine("using System;");
  26. classSource.AppendLine("using System.IO;");
  27. classSource.AppendLine();
  28. //生成CSharp数据类
  29. if(excelMediumData.isCreateCSharp)
  30. {
  31. //生成行数据类,记录每行数据
  32. classSource.AppendLine(CreateExcelRowItemClass(itemClassName,excelMediumData));
  33. classSource.AppendLine();
  34. //生成整体数据类,记录整个Excel的所有行数据
  35. classSource.AppendLine(CreateExcelAllDataClass(dataClassName,itemClassName,excelMediumData));
  36. classSource.AppendLine();
  37. }
  38. //生成Asset创建类
  39. if(excelMediumData.isCreateAssignment)
  40. {
  41. //生成Asset操作类,用于自动创建Excel对应的Asset文件并赋值
  42. classSource.AppendLine(CreateExcelAssetClass(excelMediumData));
  43. classSource.AppendLine();
  44. }
  45. //
  46. return classSource.ToString();
  47. }
  48. //----------
  49. //生成行数据类
  50. private static string CreateExcelRowItemClass(string itemClassName,ExcelMediumData excelMediumData)
  51. {
  52. //生成Excel行数据类
  53. StringBuilder classSource = new StringBuilder();
  54. //类名
  55. classSource.AppendLine("[Serializable]");
  56. classSource.AppendLine($"public class {itemClassName} : ExcelItemBase");
  57. classSource.AppendLine("{");
  58. //声明所有字段
  59. for(int i = 0; i < excelMediumData.propertyNameArray.Length; i++)
  60. {
  61. //跳过注释字段
  62. if(excelMediumData.annotationColList.Contains(i))
  63. continue;
  64. //添加注释
  65. if(i < excelMediumData.propertyNodeArray.Length)
  66. {
  67. string propertyNode = excelMediumData.propertyNodeArray[i];
  68. if(!string.IsNullOrEmpty(propertyNode))
  69. {
  70. classSource.AppendLine("\t/// <summary>");
  71. classSource.AppendLine($"\t/// {propertyNode}");
  72. classSource.AppendLine("\t/// </summary>>");
  73. }
  74. }
  75. //声明行数据类的字段
  76. string propertyName = excelMediumData.propertyNameArray[i];
  77. string propertyType = excelMediumData.propertyTypeArray[i];
  78. string typeStr = GetPropertyType(propertyType);
  79. classSource.AppendLine($"\tpublic {typeStr} {propertyName};");
  80. }
  81. classSource.AppendLine("}");
  82. return classSource.ToString();
  83. }
  84. //----------
  85. //生成整体数据类
  86. private static string CreateExcelAllDataClass(string dataClassName,string itemClassName,ExcelMediumData excelMediumData)
  87. {
  88. StringBuilder classSource = new StringBuilder();
  89. //类名
  90. classSource.AppendLine($"public class {dataClassName} : ExcelDataBase<{itemClassName}>");
  91. classSource.AppendLine("{");
  92. //声明字段,行数据类数组
  93. classSource.AppendLine($"\tpublic {itemClassName}[] items;");
  94. classSource.AppendLine();
  95. //id字段类型
  96. string idTypeStr = GetPropertyType(excelMediumData.propertyTypeArray[0]);
  97. //声明字典
  98. classSource.AppendLine($"\tpublic Dictionary<{idTypeStr},{itemClassName}> itemDic = new Dictionary<{idTypeStr},{itemClassName}>();");
  99. classSource.AppendLine();
  100. //字段初始化方法
  101. classSource.AppendLine("\tpublic void Init()");
  102. classSource.AppendLine("\t{");
  103. classSource.AppendLine("\t\titemDic.Clear();");
  104. classSource.AppendLine("\t\tif(items != null && items.Length > 0)");
  105. classSource.AppendLine("\t\t{");
  106. classSource.AppendLine("\t\t\tfor(int i = 0; i < items.Length; i++)");
  107. classSource.AppendLine("\t\t\t{");
  108. classSource.AppendLine("\t\t\t\titemDic.Add(items[i].id, items[i]);");
  109. classSource.AppendLine("\t\t\t}");
  110. classSource.AppendLine("\t\t}");
  111. classSource.AppendLine("\t}");
  112. classSource.AppendLine();
  113. //字典获取方法
  114. classSource.AppendLine($"\tpublic {itemClassName} Get{itemClassName}({idTypeStr} id)");
  115. classSource.AppendLine("\t{");
  116. classSource.AppendLine("\t\tif(itemDic.ContainsKey(id))");
  117. classSource.AppendLine("\t\t\treturn itemDic[id];");
  118. classSource.AppendLine("\t\telse");
  119. classSource.AppendLine("\t\t\treturn null;");
  120. classSource.AppendLine("\t}");
  121. //每个字段Get函数
  122. classSource.AppendLine("\t#region --- Get Method ---");
  123. classSource.AppendLine();
  124. for(int i = 1; i < excelMediumData.propertyNameArray.Length; i++)
  125. {
  126. if(excelMediumData.annotationColList.Contains(i))
  127. continue;
  128. string propertyName = excelMediumData.propertyNameArray[i];
  129. string propertyType = excelMediumData.propertyTypeArray[i];
  130. //每个字段Get函数
  131. classSource.AppendLine(CreateCodePropertyMethod(itemClassName,idTypeStr,propertyName,propertyType));
  132. }
  133. classSource.AppendLine("\t#endregion");
  134. classSource.AppendLine("}");
  135. return classSource.ToString();
  136. }
  137. //生成数据字段对应Get方法
  138. private static string CreateCodePropertyMethod(string itemClassName,string idTypeStr,string propertyName,string propertyType)
  139. {
  140. StringBuilder methodBuilder = new StringBuilder();
  141. string itemNameStr = propertyName.FirstOrDefault().ToString().ToUpper() + propertyName.Substring(1);
  142. string itemTypeStr = GetPropertyType(propertyType);
  143. //字段Get函数
  144. methodBuilder.AppendLine($"\tpublic {itemTypeStr} Get{itemNameStr}({idTypeStr} id)");
  145. methodBuilder.AppendLine("\t{");
  146. methodBuilder.AppendLine($"\t\tvar item = Get{itemClassName}(id);");
  147. methodBuilder.AppendLine("\t\tif(item == null)");
  148. methodBuilder.AppendLine("\t\t\treturn default;");
  149. methodBuilder.AppendLine($"\t\treturn item.{propertyName};");
  150. methodBuilder.AppendLine("\t}");
  151. //如果是一维数组
  152. if(propertyType.Contains("[]"))
  153. {
  154. //typeStr:int[]或IntArr[] ,返回值:int或IntArr
  155. //string itemTypeStr1d = GetPropertyType(propertyType.Replace("[]",""));
  156. string itemTypeStr1d = itemTypeStr.Replace("[]","");
  157. methodBuilder.AppendLine($"\tpublic {itemTypeStr1d} Get{itemNameStr}({idTypeStr} id, int index)");
  158. methodBuilder.AppendLine("\t{");
  159. methodBuilder.AppendLine($"\t\tvar item0 = Get{itemClassName} (id);");
  160. methodBuilder.AppendLine("\t\tif(item0 == null)");
  161. methodBuilder.AppendLine("\t\t\treturn default;");
  162. methodBuilder.AppendLine($"\t\tvar item1 = item0.{propertyName};");
  163. methodBuilder.AppendLine("\t\tif(item1 == null || index < 0 || index >= item1.Length)");
  164. methodBuilder.AppendLine("\t\t\treturn default;");
  165. methodBuilder.AppendLine("\t\treturn item1[index];");
  166. methodBuilder.AppendLine("\t}");
  167. }
  168. //如果是二维数组
  169. if(propertyType.Contains("[][]"))
  170. {
  171. //propertyType:int[][], 返回值:int
  172. string itemTypeStr1d = GetPropertyType(propertyType.Replace("[][]",""));
  173. methodBuilder.AppendLine($"\tpublic {itemTypeStr1d} Get{itemNameStr}({idTypeStr} id, int index1, int index2)");
  174. methodBuilder.AppendLine("\t{");
  175. methodBuilder.AppendLine($"\t\tvar item0 = Get{itemClassName}(id);");
  176. methodBuilder.AppendLine("\t\tif(item0 == null)");
  177. methodBuilder.AppendLine("\t\t\treturn default;");
  178. methodBuilder.AppendLine($"\t\tvar item1 = item0.{propertyName};");
  179. methodBuilder.AppendLine("\t\tif(item1 == null || index1 < 0 || index1 >= item1.Length)");
  180. methodBuilder.AppendLine("\t\t\treturn default;");
  181. methodBuilder.AppendLine("\t\tvar item2 = item1[index1];");
  182. methodBuilder.AppendLine("\t\tif(item2.array == null || index2 < 0 || index2 >= item2.array.Length)");
  183. methodBuilder.AppendLine("\t\t\treturn default;");
  184. methodBuilder.AppendLine("\t\treturn item2.array[index2];");
  185. methodBuilder.AppendLine("\t}");
  186. }
  187. //
  188. return methodBuilder.ToString();
  189. }
  190. //----------
  191. //生成Asset创建类
  192. private static string CreateExcelAssetClass(ExcelMediumData excelMediumData)
  193. {
  194. string itemClassName = excelMediumData.excelName + "ExcelItem";
  195. string dataClassName = excelMediumData.excelName + "ExcelData";
  196. string assignmentClassName = excelMediumData.excelName + "AssetAssignment";
  197. StringBuilder classSource = new StringBuilder();
  198. classSource.AppendLine("#if UNITY_EDITOR");
  199. //类名
  200. classSource.AppendLine($"public class {assignmentClassName}");
  201. classSource.AppendLine("{");
  202. //方法名
  203. classSource.AppendLine("\tpublic static bool CreateAsset(ExcelMediumData excelMediumData, string excelAssetPath)");
  204. //方法体,若有需要可加入try/catch
  205. classSource.AppendLine("\t{");
  206. classSource.AppendLine("\t\tvar allRowItemDicList = excelMediumData.GetAllRowItemDicList();");
  207. classSource.AppendLine("\t\tif(allRowItemDicList == null || allRowItemDicList.Count == 0)");
  208. classSource.AppendLine("\t\t\treturn false;");
  209. classSource.AppendLine();
  210. classSource.AppendLine("\t\tint rowCount = allRowItemDicList.Count;");
  211. classSource.AppendLine($"\t\t{dataClassName} excelDataAsset = ScriptableObject.CreateInstance<{dataClassName}>();");
  212. classSource.AppendLine($"\t\texcelDataAsset.items = new {itemClassName}[rowCount];");
  213. classSource.AppendLine();
  214. classSource.AppendLine("\t\tfor(int i = 0; i < rowCount; i++)");
  215. classSource.AppendLine("\t\t{");
  216. classSource.AppendLine("\t\t\tvar itemRowDic = allRowItemDicList[i];");
  217. classSource.AppendLine($"\t\t\texcelDataAsset.items[i] = new {itemClassName}();");
  218. for(int i = 0; i < excelMediumData.propertyNameArray.Length; i++)
  219. {
  220. if(excelMediumData.annotationColList.Contains(i))
  221. continue;
  222. string propertyName = excelMediumData.propertyNameArray[i];
  223. string propertyType = excelMediumData.propertyTypeArray[i];
  224. classSource.Append($"\t\t\texcelDataAsset.items[i].{propertyName} = ");
  225. classSource.Append(AssignmentCodeProperty(propertyName,propertyType));
  226. classSource.AppendLine(";");
  227. }
  228. classSource.AppendLine("\t\t}");
  229. classSource.AppendLine("\t\tif(!Directory.Exists(excelAssetPath))");
  230. classSource.AppendLine("\t\t\tDirectory.CreateDirectory(excelAssetPath);");
  231. classSource.AppendLine($"\t\tstring fullPath = Path.Combine(excelAssetPath,typeof({dataClassName}).Name) + \".asset\";");
  232. classSource.AppendLine("\t\tUnityEditor.AssetDatabase.DeleteAsset(fullPath);");
  233. classSource.AppendLine("\t\tUnityEditor.AssetDatabase.CreateAsset(excelDataAsset,fullPath);");
  234. classSource.AppendLine("\t\tUnityEditor.AssetDatabase.Refresh();");
  235. classSource.AppendLine("\t\treturn true;");
  236. classSource.AppendLine("\t}");
  237. //
  238. classSource.AppendLine("}");
  239. classSource.AppendLine("#endif");
  240. return classSource.ToString();
  241. }
  242. //声明Asset操作类字段
  243. private static string AssignmentCodeProperty(string propertyName,string propertyType)
  244. {
  245. string stringValue = $"itemRowDic[\"{propertyName}\"]";
  246. string typeStr = GetPropertyType(propertyType);
  247. switch(typeStr)
  248. {
  249. //字段
  250. case "int":
  251. return "StringUtility.StringToInt(" + stringValue + ")";
  252. case "float":
  253. return "StringUtility.StringToFloat(" + stringValue + ")";
  254. case "bool":
  255. return "StringUtility.StringToBool(" + stringValue + ")";
  256. case "Vector2":
  257. return "StringUtility.StringToVector2(" + stringValue + ")";
  258. case "Vector3":
  259. return "StringUtility.StringToVector3(" + stringValue + ")";
  260. case "Vector2Int":
  261. return "StringUtility.StringToVector2Int(" + stringValue + ")";
  262. case "Vector3Int":
  263. return "StringUtility.StringToVector3Int(" + stringValue + ")";
  264. case "Color":
  265. return "StringUtility.StringToColor(" + stringValue + ")";
  266. case "Color32":
  267. return "StringUtility.StringToColor32(" + stringValue + ")";
  268. case "string":
  269. return stringValue;
  270. //一维
  271. case "int[]":
  272. return "StringUtility.StringToIntArray(" + stringValue + ")";
  273. case "float[]":
  274. return "StringUtility.StringToFloatArray(" + stringValue + ")";
  275. case "bool[]":
  276. return "StringUtility.StringToBoolArray(" + stringValue + ")";
  277. case "Vector2[]":
  278. return "StringUtility.StringToVector2Array(" + stringValue + ")";
  279. case "Vector3[]":
  280. return "StringUtility.StringToVector3Array(" + stringValue + ")";
  281. case "Vector2Int[]":
  282. return "StringUtility.StringToVector2IntArray(" + stringValue + ")";
  283. case "Vector3Int[]":
  284. return "StringUtility.StringToVector3IntArray(" + stringValue + ")";
  285. case "Color[]":
  286. return "StringUtility.StringToColorArray(" + stringValue + ")";
  287. case "Color32[]":
  288. return "StringUtility.StringToColor32Array(" + stringValue + ")";
  289. case "string[]":
  290. return "StringUtility.StringToStringArray(" + stringValue + ")";
  291. //二维
  292. case "IntArr[]":
  293. return "StringUtility.StringToIntArray2D(" + stringValue + ")";
  294. case "FloatArr[]":
  295. return "StringUtility.StringToFloatArray2D(" + stringValue + ")";
  296. case "BoolArr[]":
  297. return "StringUtility.StringToBoolArray2D(" + stringValue + ")";
  298. case "Vector2Arr[]":
  299. return "StringUtility.StringToVector2Array2D(" + stringValue + ")";
  300. case "Vector3Arr[]":
  301. return "StringUtility.StringToVector3Array2D(" + stringValue + ")";
  302. case "Vector2IntArr[]":
  303. return "StringUtility.StringToVector2IntArray2D(" + stringValue + ")";
  304. case "Vector3IntArr[]":
  305. return "StringUtility.StringToVector3IntArray2D(" + stringValue + ")";
  306. case "ColorArr[]":
  307. return "StringUtility.StringToColorArray2D(" + stringValue + ")";
  308. case "Color32Arr[]":
  309. return "StringUtility.StringToColor32Array2D(" + stringValue + ")";
  310. case "StringArr[]":
  311. return "StringUtility.StringToStringArray2D(" + stringValue + ")";
  312. default:
  313. //枚举
  314. if(propertyType.StartsWith("enum"))
  315. {
  316. string enumType = propertyType.Split('|').FirstOrDefault();
  317. string enumName = propertyType.Split('|').LastOrDefault();
  318. if(enumType == "enum")
  319. return "StringUtility.StringToEnum<" + enumName + ">(" + stringValue + ")";
  320. else if(enumType == "enum[]")
  321. return "StringUtility.StringToEnumArray<" + enumName + ">(" + stringValue + ")";
  322. else if(enumType == "enum[][]")
  323. return "StringUtility.StringToEnumArray2D<" + enumName + ">(" + stringValue + ")";
  324. }
  325. return stringValue;
  326. }
  327. }
  328. //判断字段类型
  329. private static string GetPropertyType(string propertyType)
  330. {
  331. string lowerType = propertyType.ToLower();
  332. switch(lowerType)
  333. {
  334. case "int":
  335. return "int";
  336. case "int[]":
  337. return "int[]";
  338. case "int[][]":
  339. return "IntArr[]";
  340. case "float":
  341. return "float";
  342. case "float[]":
  343. return "float[]";
  344. case "float[][]":
  345. return "FloatArr[]";
  346. case "bool":
  347. return "bool";
  348. case "bool[]":
  349. return "bool[]";
  350. case "bool[][]":
  351. return "BoolArr[]";
  352. case "string":
  353. return "string";
  354. case "string[]":
  355. return "string[]";
  356. case "string[][]":
  357. return "StringArr[]";
  358. case "vector2":
  359. return "Vector2";
  360. case "vector2[]":
  361. return "Vector2[]";
  362. case "vector2[][]":
  363. return "Vector2Arr[]";
  364. case "vector2int":
  365. return "Vector2Int";
  366. case "vector2int[]":
  367. return "Vector2Int[]";
  368. case "vector2int[][]":
  369. return "Vector2IntArr[]";
  370. case "vector3":
  371. return "Vector3";
  372. case "vector3[]":
  373. return "Vector3[]";
  374. case "vector3[][]":
  375. return "Vector3Arr[]";
  376. case "vector3int":
  377. return "Vector3Int";
  378. case "vector3int[]":
  379. return "Vector3Int[]";
  380. case "vector3int[][]":
  381. return "Vector3IntArr[]";
  382. case "color":
  383. return "Color";
  384. case "color[]":
  385. return "Color[]";
  386. case "color[][]":
  387. return "ColorArr[]";
  388. case "color32":
  389. return "Color32";
  390. case "color32[]":
  391. return "Color32[]";
  392. case "color32[][]":
  393. return "Color32Arr[]";
  394. default:
  395. if(propertyType.StartsWith("enum"))
  396. {
  397. string enumType = propertyType.Split('|').FirstOrDefault();
  398. string enumName = propertyType.Split('|').LastOrDefault();
  399. switch(enumType)
  400. {
  401. case "enum":
  402. return enumName;
  403. case "enum[]":
  404. return $"{enumName}[]";
  405. case "enum[][]":
  406. return $"EnumArr<{enumName}>[]";
  407. default:
  408. break;
  409. }
  410. }
  411. return "string";
  412. }
  413. }
  414. }