Newer
Older
DungeonShooting / DungeonShooting_ExcelTool / ExcelGenerator.cs
  1. using System.Text.Json;
  2. using System.Text.RegularExpressions;
  3. using NPOI.SS.UserModel;
  4. using NPOI.XSSF.UserModel;
  5.  
  6. public static class ExcelGenerator
  7. {
  8. private const string CodeOutPath = "src/config/";
  9. private const string JsonOutPath = "resource/config/";
  10. private const string ExcelFilePath = "excelFile";
  11.  
  12. private static HashSet<string> _excelNames = new HashSet<string>();
  13.  
  14. private enum CollectionsType
  15. {
  16. None,
  17. Array,
  18. Map
  19. }
  20. private class MappingData
  21. {
  22.  
  23. public string TypeStr;
  24. public string TypeName;
  25. public CollectionsType CollectionsType;
  26. public bool IsRefExcel;
  27. public string RefTypeStr;
  28. public string RefTypeName;
  29.  
  30. public MappingData(string typeStr, string typeName, CollectionsType collectionsType)
  31. {
  32. TypeStr = typeStr;
  33. TypeName = typeName;
  34. CollectionsType = collectionsType;
  35. IsRefExcel = false;
  36. }
  37. public MappingData(string typeStr, string typeName, CollectionsType collectionsType, string refTypeStr, string refTypeName)
  38. {
  39. TypeStr = typeStr;
  40. TypeName = typeName;
  41. CollectionsType = collectionsType;
  42. IsRefExcel = true;
  43. RefTypeStr = refTypeStr;
  44. RefTypeName = refTypeName;
  45. }
  46. }
  47.  
  48. private class ExcelData
  49. {
  50. public string TableName;
  51. public string OutCode;
  52. public List<string> ColumnNames = new List<string>();
  53. public Dictionary<string, MappingData> ColumnMappingData = new Dictionary<string, MappingData>();
  54. public Dictionary<string, Type> ColumnType = new Dictionary<string, Type>();
  55. public List<Dictionary<string, object>> DataList = new List<Dictionary<string, object>>();
  56. }
  57.  
  58. public static bool ExportExcel()
  59. {
  60. return ExportExcel(ExcelFilePath, JsonOutPath, CodeOutPath);
  61. }
  62. public static bool ExportExcel(string excelFilePath, string jsonOutPath, string codeOutPath)
  63. {
  64. Console.WriteLine("当前路径: " + Environment.CurrentDirectory);
  65. Console.WriteLine("excel路径: " + excelFilePath);
  66. Console.WriteLine("json输出路径: " + jsonOutPath);
  67. Console.WriteLine("cs代码输出路径: " + codeOutPath);
  68. try
  69. {
  70. var excelDataList = new List<ExcelData>();
  71. var directoryInfo = new DirectoryInfo(excelFilePath);
  72. if (directoryInfo.Exists)
  73. {
  74. var fileInfos = directoryInfo.GetFiles();
  75. //记录文件
  76. foreach (var fileInfo in fileInfos)
  77. {
  78. var fileName = Path.GetFileNameWithoutExtension(fileInfo.Name).FirstToUpper();
  79. _excelNames.Add(fileName);
  80. }
  81. //读取配置文件
  82. foreach (var fileInfo in fileInfos)
  83. {
  84. if (fileInfo.Extension == ".xlsx")
  85. {
  86. if (fileInfo.Name == "ExcelConfig.xlsx")
  87. {
  88. throw new Exception("excel表文件名称不允许叫'ExcelConfig.xlsx'!");
  89. }
  90. Console.WriteLine("excel表: " + fileInfo.FullName);
  91. excelDataList.Add(ReadExcel(fileInfo.FullName));
  92. }
  93. }
  94. }
  95.  
  96. Console.WriteLine($"一共检测到excel表共{excelDataList.Count}张.");
  97. if (excelDataList.Count == 0)
  98. {
  99. return true;
  100. }
  101. if (Directory.Exists(codeOutPath))
  102. {
  103. Directory.Delete(codeOutPath, true);
  104. }
  105. if (Directory.Exists(jsonOutPath))
  106. {
  107. Directory.Delete(jsonOutPath, true);
  108. }
  109. Directory.CreateDirectory(codeOutPath);
  110. Directory.CreateDirectory(jsonOutPath);
  111. //保存配置和代码
  112. foreach (var excelData in excelDataList)
  113. {
  114. File.WriteAllText(codeOutPath + "ExcelConfig_" + excelData.TableName + ".cs", excelData.OutCode);
  115. var config = new JsonSerializerOptions();
  116. config.WriteIndented = true;
  117. File.WriteAllText(jsonOutPath + excelData.TableName + ".json", JsonSerializer.Serialize(excelData.DataList, config));
  118. }
  119. //生成加载代码
  120. var code = GeneratorInitCode(excelDataList);
  121. File.WriteAllText(codeOutPath + "ExcelConfig.cs", code);
  122. }
  123. catch (Exception e)
  124. {
  125. PrintError(e.ToString());
  126. return false;
  127. }
  128.  
  129. return true;
  130. }
  131.  
  132. private static string GeneratorInitCode(List<ExcelData> excelList)
  133. {
  134. var code = $"using System;\n";
  135. code += $"using System.Collections.Generic;\n";
  136. code += $"using System.Text.Json;\n";
  137. code += $"using Godot;\n";
  138. code += $"\n";
  139. code += $"namespace Config;\n";
  140. code += $"\n";
  141. code += $"public static partial class ExcelConfig\n";
  142. code += $"{{\n";
  143.  
  144. var fieldCode = "";
  145. var callFuncCode = "";
  146. var callInitRefFuncCode = "";
  147. var funcCode = "";
  148. var initRefFuncCode = "";
  149. foreach (var excelData in excelList)
  150. {
  151. var idName = excelData.ColumnNames[0];
  152. var idTypeStr = excelData.ColumnMappingData[idName].TypeStr;
  153. //---------------------------- 引用其他表处理 ----------------------------
  154. var hasRefColumn = false;
  155. var refColumnNoneCode = "";
  156. foreach (var columnName in excelData.ColumnNames)
  157. {
  158. var mappingData = excelData.ColumnMappingData[columnName];
  159. if (mappingData.IsRefExcel)
  160. {
  161. hasRefColumn = true;
  162. if (mappingData.CollectionsType == CollectionsType.None)
  163. {
  164. refColumnNoneCode += $" if (!string.IsNullOrEmpty(item.__{columnName}))\n";
  165. refColumnNoneCode += $" {{\n";
  166. refColumnNoneCode += $" item.{columnName} = {mappingData.RefTypeName}_Map[item.__{columnName}];\n";
  167. refColumnNoneCode += $" }}\n";
  168. }
  169. else if (mappingData.CollectionsType == CollectionsType.Array)
  170. {
  171. refColumnNoneCode += $" if (item.__{columnName} != null)\n";
  172. refColumnNoneCode += $" {{\n";
  173. refColumnNoneCode += $" item.{columnName} = new {mappingData.RefTypeName}[item.__{columnName}.Length];\n";
  174. refColumnNoneCode += $" for (var i = 0; i < item.__{columnName}.Length; i++)\n";
  175. refColumnNoneCode += $" {{\n";
  176. refColumnNoneCode += $" item.{columnName}[i] = {mappingData.RefTypeName}_Map[item.__{columnName}[i]];\n";
  177. refColumnNoneCode += $" }}\n";
  178. refColumnNoneCode += $" }}\n";
  179. }
  180. else
  181. {
  182. refColumnNoneCode += $" if (item.__{columnName} != null)\n";
  183. refColumnNoneCode += $" {{\n";
  184. refColumnNoneCode += $" item.{columnName} = new {mappingData.RefTypeStr}();\n";
  185. refColumnNoneCode += $" foreach (var pair in item.__{columnName})\n";
  186. refColumnNoneCode += $" {{\n";
  187. refColumnNoneCode += $" item.{columnName}.Add(pair.Key, {mappingData.RefTypeName}_Map[pair.Value]);\n";
  188. refColumnNoneCode += $" }}\n";
  189. refColumnNoneCode += $" }}\n";
  190. }
  191. refColumnNoneCode += $"\n";
  192. }
  193. }
  194. //----------------------------- 数据集合 ------------------------------------
  195. fieldCode += $" /// <summary>\n";
  196. fieldCode += $" /// {excelData.TableName}.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同\n";
  197. fieldCode += $" /// </summary>\n";
  198. fieldCode += $" public static List<{excelData.TableName}> {excelData.TableName}_List {{ get; private set; }}\n";
  199. fieldCode += $" /// <summary>\n";
  200. fieldCode += $" /// {excelData.TableName}.xlsx表数据集合, 里 Map 形式存储, key 为 {idName}\n";
  201. fieldCode += $" /// </summary>\n";
  202. fieldCode += $" public static Dictionary<{idTypeStr}, {excelData.TableName}> {excelData.TableName}_Map {{ get; private set; }}\n";
  203. fieldCode += $"\n";
  204. //------------------------------- 初始化函数 -------------------------------------
  205. callFuncCode += $" _Init{excelData.TableName}Config();\n";
  206. funcCode += $" private static void _Init{excelData.TableName}Config()\n";
  207. funcCode += $" {{\n";
  208. funcCode += $" try\n";
  209. funcCode += $" {{\n";
  210. funcCode += $" var text = _ReadConfigAsText(\"res://resource/config/{excelData.TableName}.json\");\n";
  211. if (hasRefColumn) //存在引用列
  212. {
  213. funcCode += $" {excelData.TableName}_List = new List<{excelData.TableName}>(JsonSerializer.Deserialize<List<Ref_{excelData.TableName}>>(text));\n";
  214. }
  215. else
  216. {
  217. funcCode += $" {excelData.TableName}_List = JsonSerializer.Deserialize<List<{excelData.TableName}>>(text);\n";
  218. }
  219. funcCode += $" {excelData.TableName}_Map = new Dictionary<{idTypeStr}, {excelData.TableName}>();\n";
  220. funcCode += $" foreach (var item in {excelData.TableName}_List)\n";
  221. funcCode += $" {{\n";
  222. funcCode += $" {excelData.TableName}_Map.Add(item.{idName}, item);\n";
  223. funcCode += $" }}\n";
  224. funcCode += $" }}\n";
  225. funcCode += $" catch (Exception e)\n";
  226. funcCode += $" {{\n";
  227. funcCode += $" GD.PrintErr(e.ToString());\n";
  228. funcCode += $" throw new Exception(\"初始化表'{excelData.TableName}'失败!\");\n";
  229. funcCode += $" }}\n";
  230. funcCode += $" }}\n";
  231.  
  232. //------------------------------- 初始化引用 ---------------------------------
  233. if (hasRefColumn)
  234. {
  235. callInitRefFuncCode += $" _Init{excelData.TableName}Ref();\n";
  236.  
  237. initRefFuncCode += $" private static void _Init{excelData.TableName}Ref()\n";
  238. initRefFuncCode += $" {{\n";
  239. initRefFuncCode += $" foreach (Ref_{excelData.TableName} item in {excelData.TableName}_List)\n";
  240. initRefFuncCode += $" {{\n";
  241. initRefFuncCode += $" try\n";
  242. initRefFuncCode += $" {{\n";
  243. initRefFuncCode += refColumnNoneCode;
  244. initRefFuncCode += $" }}\n";
  245. initRefFuncCode += $" catch (Exception e)\n";
  246. initRefFuncCode += $" {{\n";
  247. initRefFuncCode += $" GD.PrintErr(e.ToString());\n";
  248. initRefFuncCode += $" throw new Exception(\"初始化'{excelData.TableName}'引用其他表数据失败, 当前行id: \" + item.Id);\n";
  249. initRefFuncCode += $" }}\n";
  250. initRefFuncCode += $" }}\n";
  251. initRefFuncCode += $" }}\n";
  252. }
  253. }
  254.  
  255. code += fieldCode;
  256. code += $"\n";
  257. code += $" private static bool _init = false;\n";
  258. code += $" /// <summary>\n";
  259. code += $" /// 初始化所有配置表数据\n";
  260. code += $" /// </summary>\n";
  261. code += $" public static void Init()\n";
  262. code += $" {{\n";
  263. code += $" if (_init) return;\n";
  264. code += $" _init = true;\n";
  265. code += $"\n";
  266. code += callFuncCode;
  267. code += $"\n";
  268. code += callInitRefFuncCode;
  269. code += $" }}\n";
  270. code += funcCode;
  271. code += $"\n";
  272. code += initRefFuncCode;
  273. code += $" private static string _ReadConfigAsText(string path)\n";
  274. code += $" {{\n";
  275. code += $" var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);\n";
  276. code += $" var asText = file.GetAsText();\n";
  277. code += $" file.Dispose();\n";
  278. code += $" return asText;\n";
  279. code += $" }}\n";
  280. code += $"}}";
  281. return code;
  282. }
  283. private static ExcelData ReadExcel(string excelPath)
  284. {
  285. var excelData = new ExcelData();
  286. //文件名称
  287. var fileName = Path.GetFileNameWithoutExtension(excelPath).FirstToUpper();
  288. excelData.TableName = fileName;
  289. //输出代码
  290. var outStr = $"using System.Text.Json.Serialization;\n";
  291. outStr += $"using System.Collections.Generic;\n\n";
  292. outStr += $"namespace Config;\n\n";
  293. outStr += $"public static partial class ExcelConfig\n{{\n";
  294. outStr += $" public class {fileName}\n";
  295. outStr += $" {{\n";
  296. //继承的带有引用其他表的类代码
  297. var outRefStr = "";
  298. var cloneFuncStr = $" /// <summary>\n";
  299. cloneFuncStr += $" /// 返回浅拷贝出的新对象\n";
  300. cloneFuncStr += $" /// </summary>\n";
  301. cloneFuncStr += $" public {fileName} Clone()\n";
  302. cloneFuncStr += $" {{\n";
  303. cloneFuncStr += $" var inst = new {fileName}();\n";
  304. var sourceFile = excelPath;
  305.  
  306. //行数
  307. var rowCount = -1;
  308. //列数
  309. var columnCount = -1;
  310. //加载表数据
  311. var workbook = new XSSFWorkbook(sourceFile);
  312. using (workbook)
  313. {
  314. var sheet1 = workbook.GetSheet("Sheet1");
  315. rowCount = sheet1.LastRowNum;
  316. //先解析表中的列名, 注释, 类型
  317. var names = sheet1.GetRow(0);
  318. var descriptions = sheet1.GetRow(1);
  319. var types = sheet1.GetRow(2);
  320. columnCount = names.LastCellNum;
  321. foreach (var cell in names)
  322. {
  323. //字段名称
  324. var field = GetCellStringValue(cell);
  325. if (string.IsNullOrEmpty(field))
  326. {
  327. if (cell.ColumnIndex == 0)
  328. {
  329. throw new Exception($"表'{fileName}'的列数为0!");
  330. }
  331. //到达最后一列了
  332. columnCount = cell.ColumnIndex;
  333. break;
  334. }
  335. field = field.FirstToUpper();
  336. excelData.ColumnNames.Add(field);
  337. if (field == "Clone")
  338. {
  339. throw new Exception($"表'{fileName}'中不允许有'Clone'字段!");
  340. }
  341.  
  342. var descriptionCell = descriptions.GetCell(cell.ColumnIndex);
  343. //描述
  344. string description;
  345. if (descriptionCell != null)
  346. {
  347. description = GetCellStringValue(descriptionCell).Replace("\n", " <br/>\n /// ");
  348. }
  349. else
  350. {
  351. description = "";
  352. }
  353. //类型
  354. var typeString = GetCellStringValue(types.GetCell(cell.ColumnIndex));
  355. if (string.IsNullOrEmpty(typeString))
  356. {
  357. throw new Exception($"表'{fileName}'中'{field}'这一列类型为空!");
  358. }
  359. //尝试解析类型
  360. MappingData mappingData;
  361. try
  362. {
  363. mappingData = ConvertToType(typeString.Replace(" ", ""));
  364. }
  365. catch (Exception e)
  366. {
  367. PrintError(e.ToString());
  368. throw new Exception($"表'{fileName}'中'{field}'这一列类型描述语法错误: {typeString}");
  369. }
  370. if (!excelData.ColumnMappingData.TryAdd(field, mappingData))
  371. {
  372. throw new Exception($"表'{fileName}'中存在相同名称的列: '{field}'!");
  373. }
  374. outStr += $" /// <summary>\n";
  375. outStr += $" /// {description}\n";
  376. outStr += $" /// </summary>\n";
  377. if (!mappingData.IsRefExcel) //没有引用其他表
  378. {
  379. outStr += $" [JsonInclude]\n";
  380. outStr += $" public {mappingData.TypeStr} {field};\n\n";
  381. }
  382. else
  383. {
  384. outStr += $" public {mappingData.RefTypeStr} {field};\n\n";
  385. }
  386.  
  387. if (mappingData.IsRefExcel) //引用其他表
  388. {
  389. if (string.IsNullOrEmpty(outRefStr))
  390. {
  391. outRefStr += $" private class Ref_{fileName} : {fileName}\n";
  392. outRefStr += $" {{\n";
  393. }
  394. outRefStr += $" [JsonInclude]\n";
  395. outRefStr += $" public {mappingData.TypeStr} __{field};\n\n";
  396. }
  397. cloneFuncStr += $" inst.{field} = {field};\n";
  398. }
  399. cloneFuncStr += " return inst;\n";
  400. cloneFuncStr += " }\n";
  401. outStr += cloneFuncStr;
  402. outStr += " }\n";
  403.  
  404. if (!string.IsNullOrEmpty(outRefStr))
  405. {
  406. outRefStr += " }\n";
  407. outStr += outRefStr;
  408. }
  409. outStr += "}";
  410. //解析字段类型
  411. foreach (var kv in excelData.ColumnMappingData)
  412. {
  413. var typeName = kv.Value.TypeName;
  414. var type = Type.GetType(typeName);
  415. if (type == null)
  416. {
  417. throw new Exception($"表'{fileName}'中'{kv.Key}'这一列类型未知! " + kv.Value.TypeStr);
  418. }
  419. excelData.ColumnType.Add(kv.Key, type);
  420. }
  421.  
  422. //解析数据
  423. for (int i = 3; i <= rowCount; i++)
  424. {
  425. Dictionary<string, object> data = null;
  426. var row = sheet1.GetRow(i);
  427. if (row == null)
  428. {
  429. continue;
  430. }
  431. for (int j = 0; j < columnCount; j++)
  432. {
  433. var cell = row.GetCell(j);
  434. var strValue = GetCellStringValue(cell);
  435. //如果这一行的第一列数据为空, 则跳过这一行
  436. if (j == 0 && string.IsNullOrEmpty(strValue))
  437. {
  438. break;
  439. }
  440. else if (data == null)
  441. {
  442. data = new Dictionary<string, object>();
  443. excelData.DataList.Add(data);
  444. }
  445.  
  446. var fieldName = excelData.ColumnNames[j];
  447. var mappingData = excelData.ColumnMappingData[fieldName];
  448. var field = mappingData.IsRefExcel ? "__" + fieldName : fieldName;
  449. try
  450. {
  451. switch (mappingData.TypeStr)
  452. {
  453. case "bool":
  454. case "boolean":
  455. data.Add(field, GetCellBooleanValue(cell));
  456. break;
  457. case "byte":
  458. data.Add(field, Convert.ToByte(GetCellNumberValue(cell)));
  459. break;
  460. case "sbyte":
  461. data.Add(field, Convert.ToSByte(GetCellNumberValue(cell)));
  462. break;
  463. case "short":
  464. data.Add(field, Convert.ToInt16(GetCellNumberValue(cell)));
  465. break;
  466. case "ushort":
  467. data.Add(field, Convert.ToUInt16(GetCellNumberValue(cell)));
  468. break;
  469. case "int":
  470. data.Add(field, Convert.ToInt32(GetCellNumberValue(cell)));
  471. break;
  472. case "uint":
  473. data.Add(field, Convert.ToUInt32(GetCellNumberValue(cell)));
  474. break;
  475. case "long":
  476. data.Add(field, Convert.ToInt64(GetCellNumberValue(cell)));
  477. break;
  478. case "ulong":
  479. data.Add(field, Convert.ToUInt64(GetCellNumberValue(cell)));
  480. break;
  481. case "float":
  482. data.Add(field, Convert.ToSingle(GetCellNumberValue(cell)));
  483. break;
  484. case "double":
  485. data.Add(field, GetCellNumberValue(cell));
  486. break;
  487. case "string":
  488. data.Add(field, GetCellStringValue(cell));
  489. break;
  490. default:
  491. {
  492. var cellStringValue = GetCellStringValue(cell);
  493. if (cellStringValue.Length == 0)
  494. {
  495. data.Add(field, null);
  496. }
  497. else
  498. {
  499. data.Add(field, JsonSerializer.Deserialize(cellStringValue, excelData.ColumnType[fieldName]));
  500. }
  501. }
  502. break;
  503. }
  504. }
  505. catch (Exception e)
  506. {
  507. PrintError(e.ToString());
  508. throw new Exception($"解析表'{fileName}'第'{i + 1}'行第'{j + 1}'列数据时发生异常");
  509. }
  510. }
  511. }
  512. }
  513.  
  514. excelData.OutCode = outStr;
  515. return excelData;
  516. }
  517.  
  518. private static string GetCellStringValue(ICell cell)
  519. {
  520. if (cell == null)
  521. {
  522. return "";
  523. }
  524. switch (cell.CellType)
  525. {
  526. case CellType.Numeric:
  527. return cell.NumericCellValue.ToString();
  528. case CellType.String:
  529. return cell.StringCellValue;
  530. case CellType.Formula:
  531. return cell.CellFormula;
  532. case CellType.Boolean:
  533. return cell.BooleanCellValue ? "true" : "false";
  534. }
  535.  
  536. return "";
  537. }
  538.  
  539. private static double GetCellNumberValue(ICell cell)
  540. {
  541. if (cell == null)
  542. {
  543. return 0;
  544. }
  545.  
  546. return cell.NumericCellValue;
  547. }
  548.  
  549. private static bool GetCellBooleanValue(ICell cell)
  550. {
  551. if (cell == null)
  552. {
  553. return false;
  554. }
  555.  
  556. if (cell.CellType == CellType.Boolean)
  557. {
  558. return cell.BooleanCellValue;
  559. }
  560.  
  561. var value = cell.StringCellValue;
  562. if (string.IsNullOrWhiteSpace(value))
  563. {
  564. return false;
  565. }
  566.  
  567. return bool.Parse(value);
  568. }
  569.  
  570. private static MappingData ConvertToType(string str, int depth = 0)
  571. {
  572. if (Regex.IsMatch(str, "^\\w+$"))
  573. {
  574. var typeStr = TypeStrMapping(str);
  575. var typeName = TypeNameMapping(str);
  576. return new MappingData(typeStr, typeName, CollectionsType.None);
  577. }
  578. else if (Regex.IsMatch(str, "^\\$\\w+$")) //引用其他表
  579. {
  580. var realName = str.Substring(1);
  581. if (!_excelNames.Contains(realName))
  582. {
  583. throw new Exception($"引用表数据失败, 未找到表: {realName}!");
  584. }
  585.  
  586. if (depth > 1)
  587. {
  588. throw new Exception("引用表数据失败, 引用表数据仅支持放入第一层的数组和字典!");
  589. }
  590.  
  591. return new MappingData(TypeStrMapping("string"), TypeNameMapping("string"), CollectionsType.None, realName, realName);
  592. }
  593. else if (str.StartsWith('{')) //字典
  594. {
  595. var tempStr = str.Substring(1, str.Length - 2);
  596. var index = tempStr.IndexOf(':');
  597. if (index == -1)
  598. {
  599. throw new Exception("类型描述语法错误!");
  600. }
  601.  
  602. var keyStr = tempStr.Substring(0, index);
  603. if (!IsBaseType(keyStr))
  604. {
  605. throw new Exception($"字典key类型必须是基础类型!");
  606. }
  607.  
  608. var type1 = ConvertToType(keyStr, depth + 1);
  609. var type2 = ConvertToType(tempStr.Substring(index + 1), depth + 1);
  610.  
  611. var typeStr = $"Dictionary<{type1.TypeStr}, {type2.TypeStr}>";
  612. var typeName = $"System.Collections.Generic.Dictionary`2[[{type1.TypeName}],[{type2.TypeName}]]";
  613.  
  614. if (type2.IsRefExcel) //引用过其他表
  615. {
  616. var refTypeStr = $"Dictionary<{type1.TypeStr}, {type2.RefTypeStr}>";
  617. return new MappingData(typeStr, typeName, CollectionsType.Map, refTypeStr, type2.RefTypeName);
  618. }
  619.  
  620. return new MappingData(typeStr, typeName, CollectionsType.Map);
  621. }
  622. else if (str.StartsWith('[')) //数组
  623. {
  624. var tempStr = str.Substring(1, str.Length - 2);
  625. var typeData = ConvertToType(tempStr, depth + 1);
  626. var typeStr = typeData.TypeStr + "[]";
  627. var typeName = typeData.TypeName + "[]";
  628.  
  629. if (typeData.IsRefExcel) //引用过其他表
  630. {
  631. var refTypeStr = typeData.RefTypeStr + "[]";
  632. return new MappingData(typeStr, typeName, CollectionsType.Array, refTypeStr, typeData.RefTypeName);
  633. }
  634. return new MappingData(typeStr, typeName, CollectionsType.Array);
  635. }
  636. throw new Exception("类型描述语法错误!");
  637. }
  638. private static string TypeStrMapping(string typeName)
  639. {
  640. switch (typeName)
  641. {
  642. case "boolean": return "bool";
  643. case "vector2": return "SerializeVector2";
  644. case "vector3": return "SerializeVector3";
  645. case "color": return "SerializeColor";
  646. }
  647.  
  648. return typeName;
  649. }
  650.  
  651. private static string TypeNameMapping(string typeName)
  652. {
  653. switch (typeName)
  654. {
  655. case "bool":
  656. case "boolean": return typeof(bool).FullName;
  657. case "byte": return typeof(byte).FullName;
  658. case "sbyte": return typeof(sbyte).FullName;
  659. case "short": return typeof(short).FullName;
  660. case "ushort": return typeof(ushort).FullName;
  661. case "int": return typeof(int).FullName;
  662. case "uint": return typeof(uint).FullName;
  663. case "long": return typeof(long).FullName;
  664. case "ulong": return typeof(ulong).FullName;
  665. case "string": return typeof(string).FullName;
  666. case "float": return typeof(float).FullName;
  667. case "double": return typeof(double).FullName;
  668. case "vector2": return "SerializeVector2";
  669. case "vector3": return "SerializeVector3";
  670. case "color": return "SerializeColor";
  671. }
  672.  
  673. return typeName;
  674. }
  675.  
  676. private static bool IsBaseType(string typeName)
  677. {
  678. switch (typeName)
  679. {
  680. case "bool":
  681. case "boolean":
  682. case "byte":
  683. case "sbyte":
  684. case "short":
  685. case "ushort":
  686. case "int":
  687. case "uint":
  688. case "long":
  689. case "ulong":
  690. case "string":
  691. case "float":
  692. case "double":
  693. return true;
  694. }
  695.  
  696. return false;
  697. }
  698. private static void PrintError(string message)
  699. {
  700. Console.ForegroundColor = ConsoleColor.Red;
  701. Console.WriteLine(message);
  702. Console.ResetColor();
  703. }
  704. /// <summary>
  705. /// 字符串首字母小写
  706. /// </summary>
  707. public static string FirstToLower(this string str)
  708. {
  709. return str.Substring(0, 1).ToLower() + str.Substring(1);
  710. }
  711. /// <summary>
  712. /// 字符串首字母大写
  713. /// </summary>
  714. public static string FirstToUpper(this string str)
  715. {
  716. return str.Substring(0, 1).ToUpper() + str.Substring(1);
  717. }
  718. }