ExcelCodeCreater.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #if UNITY_EDITOR
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using System.Text;
  6. using System.Linq;
  7. public class ExcelCodeCreater
  8. {
  9. #region --- Create Code ---
  10. //创建代码,生成数据C#类
  11. public static string CreateCodeStrByExcelData(ExcelMediumData excelMediumData)
  12. {
  13. if (excelMediumData == null)
  14. return null;
  15. //Excel名字
  16. string excelName = excelMediumData.excelName;
  17. if (string.IsNullOrEmpty(excelName))
  18. return null;
  19. //Dictionary<字段名称, 字段类型>
  20. Dictionary<string, string> propertyNameTypeDic = excelMediumData.propertyNameTypeDic;
  21. if (propertyNameTypeDic == null || propertyNameTypeDic.Count == 0)
  22. return null;
  23. //List<一行数据>,List<Dictionary<字段名称, 一行的每个单元格字段值>>
  24. List<Dictionary<string, string>> allItemValueRowList = excelMediumData.allItemValueRowList;
  25. if (allItemValueRowList == null || allItemValueRowList.Count == 0)
  26. return null;
  27. //行数据类名
  28. string itemClassName = excelName + "ExcelItem";
  29. //整体数据类名
  30. string dataClassName = excelName + "ExcelData";
  31. //生成类
  32. StringBuilder classSource = new StringBuilder();
  33. classSource.Append("/*Auto Create, Don't Edit !!!*/\n");
  34. classSource.Append("\n");
  35. //添加引用
  36. classSource.Append("using UnityEngine;\n");
  37. classSource.Append("using System.Collections.Generic;\n");
  38. classSource.Append("using System;\n");
  39. classSource.Append("using System.IO;\n");
  40. classSource.Append("\n");
  41. //生成行数据类,记录每行数据
  42. classSource.Append(CreateExcelRowItemClass(itemClassName, propertyNameTypeDic));
  43. classSource.Append("\n");
  44. //生成整体数据类,记录整个Excel的所有行数据
  45. classSource.Append(CreateExcelDataClass(dataClassName, itemClassName));
  46. classSource.Append("\n");
  47. //生成Asset操作类,用于自动创建Excel对应的Asset文件并赋值
  48. classSource.Append(CreateExcelAssetClass(excelMediumData));
  49. classSource.Append("\n");
  50. return classSource.ToString();
  51. }
  52. //----------
  53. //生成行数据类
  54. private static StringBuilder CreateExcelRowItemClass(string itemClassName, Dictionary<string, string> propertyNameTypeDic)
  55. {
  56. //生成Excel行数据类
  57. StringBuilder classSource = new StringBuilder();
  58. classSource.Append("[Serializable]\n");
  59. classSource.Append("public class " + itemClassName + " : ExcelItemBase\n");
  60. classSource.Append("{\n");
  61. //声明所有字段
  62. foreach (var item in propertyNameTypeDic)
  63. {
  64. classSource.Append(CreateCodeProperty(item.Key, item.Value));
  65. }
  66. classSource.Append("}\n");
  67. return classSource;
  68. }
  69. //声明行数据类字段
  70. private static string CreateCodeProperty(string name, string type)
  71. {
  72. if (string.IsNullOrEmpty(name))
  73. return null;
  74. //if (name == "id")
  75. // return null;
  76. //判断字段类型
  77. if (type == "int" || type == "Int" || type == "INT")
  78. type = "int";
  79. else if (type == "float" || type == "Float" || type == "FLOAT")
  80. type = "float";
  81. else if (type == "bool" || type == "Bool" || type == "BOOL")
  82. type = "bool";
  83. else if (type.StartsWith("enum") || type.StartsWith("Enum") || type.StartsWith("ENUM"))
  84. type = type.Split('|').LastOrDefault();
  85. else
  86. type = "string";
  87. //声明
  88. string propertyStr = "\tpublic " + type + " " + name + ";\n";
  89. return propertyStr;
  90. }
  91. //----------
  92. //生成数据类
  93. private static StringBuilder CreateExcelDataClass(string dataClassName, string itemClassName)
  94. {
  95. StringBuilder classSource = new StringBuilder();
  96. classSource.Append("[CreateAssetMenu(fileName = \"" + dataClassName + "\", menuName = \"Excel To ScriptableObject/Create " + dataClassName + "\", order = 1)]\n");
  97. classSource.Append("public class " + dataClassName + " : ExcelDataBase<" + itemClassName + ">\n");
  98. classSource.Append("{\n");
  99. //声明字段,行数据类数组
  100. //classSource.Append("\tpublic " + itemClassName + "[] items;\n");
  101. classSource.Append("}\n");
  102. return classSource;
  103. }
  104. //----------
  105. //生成Asset操作类
  106. private static StringBuilder CreateExcelAssetClass(ExcelMediumData excelMediumData)
  107. {
  108. if (excelMediumData == null)
  109. return null;
  110. string excelName = excelMediumData.excelName;
  111. if (string.IsNullOrEmpty(excelName))
  112. return null;
  113. Dictionary<string, string> propertyNameTypeDic = excelMediumData.propertyNameTypeDic;
  114. if (propertyNameTypeDic == null || propertyNameTypeDic.Count == 0)
  115. return null;
  116. List<Dictionary<string, string>> allItemValueRowList = excelMediumData.allItemValueRowList;
  117. if (allItemValueRowList == null || allItemValueRowList.Count == 0)
  118. return null;
  119. string itemClassName = excelName + "ExcelItem";
  120. string dataClassName = excelName + "ExcelData";
  121. StringBuilder classSource = new StringBuilder();
  122. classSource.Append("#if UNITY_EDITOR\n");
  123. //类名
  124. classSource.Append("public class " + excelName + "AssetAssignment\n");
  125. classSource.Append("{\n");
  126. //方法名
  127. classSource.Append("\tpublic static bool CreateAsset(List<Dictionary<string, string>> allItemValueRowList, string excelAssetPath)\n");
  128. //方法体,若有需要可加入try/catch
  129. classSource.Append("\t{\n");
  130. classSource.Append("\t\tif (allItemValueRowList == null || allItemValueRowList.Count == 0)\n");
  131. classSource.Append("\t\t\treturn false;\n");
  132. classSource.Append("\t\tint rowCount = allItemValueRowList.Count;\n");
  133. classSource.Append("\t\t" + itemClassName + "[] items = new " + itemClassName + "[rowCount];\n");
  134. classSource.Append("\t\tfor (int i = 0; i < items.Length; i++)\n");
  135. classSource.Append("\t\t{\n");
  136. classSource.Append("\t\t\titems[i] = new " + itemClassName + "();\n");
  137. foreach (var item in propertyNameTypeDic)
  138. {
  139. classSource.Append("\t\t\titems[i]." + item.Key + " = ");
  140. classSource.Append(AssignmentCodeProperty("allItemValueRowList[i][\"" + item.Key + "\"]", propertyNameTypeDic[item.Key]));
  141. classSource.Append(";\n");
  142. }
  143. classSource.Append("\t\t}\n");
  144. classSource.Append("\t\t" + dataClassName + " excelDataAsset = ScriptableObject.CreateInstance<" + dataClassName + ">();\n");
  145. classSource.Append("\t\texcelDataAsset.items = items;\n");
  146. classSource.Append("\t\tif (!Directory.Exists(excelAssetPath))\n");
  147. classSource.Append("\t\t\tDirectory.CreateDirectory(excelAssetPath);\n");
  148. classSource.Append("\t\tstring pullPath = excelAssetPath + \"/\" + typeof(" + dataClassName + ").Name + \".asset\";\n");
  149. classSource.Append("\t\tUnityEditor.AssetDatabase.DeleteAsset(pullPath);\n");
  150. classSource.Append("\t\tUnityEditor.AssetDatabase.CreateAsset(excelDataAsset, pullPath);\n");
  151. classSource.Append("\t\tUnityEditor.AssetDatabase.Refresh();\n");
  152. classSource.Append("\t\treturn true;\n");
  153. classSource.Append("\t}\n");
  154. //
  155. classSource.Append("}\n");
  156. classSource.Append("#endif\n");
  157. return classSource;
  158. }
  159. //声明Asset操作类字段
  160. private static string AssignmentCodeProperty(string stringValue, string type)
  161. {
  162. //判断类型
  163. if (type == "int" || type == "Int" || type == "INT")
  164. {
  165. return "Convert.ToInt32(" + stringValue + ")";
  166. }
  167. else if (type == "float" || type == "Float" || type == "FLOAT")
  168. {
  169. return "Convert.ToSingle(" + stringValue + ")";
  170. }
  171. else if (type == "bool" || type == "Bool" || type == "BOOL")
  172. {
  173. return "Convert.ToBoolean(" + stringValue + ")";
  174. }
  175. else if (type.StartsWith("enum") || type.StartsWith("Enum") || type.StartsWith("ENUM"))
  176. {
  177. return "(" + type.Split('|').LastOrDefault() + ")(Convert.ToInt32(" + stringValue + "))";
  178. }
  179. else
  180. return stringValue;
  181. }
  182. #endregion
  183. }
  184. #endif