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