From 671b6fd440ac6b5ff9773e869ebbc6ef32eda7c6 Mon Sep 17 00:00:00 2001 From: Oliver Wong Date: Wed, 25 Mar 2026 19:11:06 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=20Excel=20?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E6=B5=81=E7=A8=8B=E4=B8=8E=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=81=A5=E5=A3=AE=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 ParsedSheet 类统一承载单个 sheet 的解析结果(SheetName / Headers / Data) - ExcelHelper 新增 ParseAllSheets(),一次打开文件完成所有 sheet 解析, 消除原先 ExcelHeaders + ExcelData 重复打开同一文件的问题 - Program.cs 在遍历层面调用 ParseAllSheets(),解析结果共享给 GenCSharpModel 和 ExportToFile,每个 xlsx 文件只打开一次 - GenModels / TableExcelExportBytes 签名改为接收 List - 修复 Program.cs 中遍历 excels 时 return 应为 continue 的 bug, 避免遇到 ~$ 临时文件时提前退出 - TypeDescriptor 新增 ReadExpression 属性,GetReadExpr 改为直接读取该属性, 消除原先通过字符串截取反推读取表达式的脆弱实现 - FileManager.WriteToFile 默认编码由 Encoding.Default 改为 UTF8(无 BOM), 确保生成的 .cs 文件跨平台编码一致 - 移除 FileManager.CreateDir 中无条件删除已存在目录的危险逻辑 - 移除 CsvHelper 中未被调用的 CSVHeader / GenBinaryData 死代码, StreamReader / FileStream 改为 using 简写形式 - 清理 Program.cs 末尾遗留的注释测试代码和无效语句,补充 TODO 标记 --- ExcelTool/CsvHelper.cs | 235 ---------------------- ExcelTool/ExcelHelper.cs | 121 +++++------ ExcelTool/FileManager.cs | 18 +- ExcelTool/Parser/GenModels.cs | 47 ++--- ExcelTool/Parser/TableExcelExportBytes.cs | 30 +-- ExcelTool/Program.cs | 49 ++--- ExcelTool/TypeRegistry.cs | 8 +- 7 files changed, 100 insertions(+), 408 deletions(-) delete mode 100644 ExcelTool/CsvHelper.cs diff --git a/ExcelTool/CsvHelper.cs b/ExcelTool/CsvHelper.cs deleted file mode 100644 index d8d9e9c..0000000 --- a/ExcelTool/CsvHelper.cs +++ /dev/null @@ -1,235 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Data; -using Spire.Xls; - -namespace ExcelTool -{ - public class CsvHelper - { - static DataTable CSVHeader(string fileName) - { - try - { - DataTable dt = new DataTable(); - FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); - StreamReader sr = new StreamReader(fs, Encoding.Default); - string strLine = ""; - string[] aryLine; - int columnCount = 0; - int lineIndex = 0; - while ((strLine = sr.ReadLine()) != null) - { - aryLine = strLine.Replace("\"", "").Replace(" ", "").Split(','); - if (lineIndex == 0) - { - columnCount = aryLine.Length; - for (int i = 0; i < columnCount; i++) - { - int typeIndex = i * 2; - int nameIndex = typeIndex + 1; - if (nameIndex < columnCount) - { - DataColumn dc = new DataColumn($"{aryLine[nameIndex]}|{aryLine[typeIndex]}"); - try - { - dt.Columns.Add(dc); - } - catch (Exception ex) - { - ConsoleHelper.WriteErrorLine(ex.ToString()); - return null; - } - } - } - } - break; - } - sr.Close(); - fs.Close(); - sr.Dispose(); - fs.Dispose(); - return dt; - } - catch (Exception ex) - { - ConsoleHelper.WriteErrorLine(ex.ToString()); - return null; - } - } - - public static DataTable CSV2DataTable(string fileName) - { - try - { - DataTable dt = new DataTable(); - FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); - StreamReader sr = new StreamReader(fs, Encoding.Default); - string strLine = ""; - string[] aryLine; - int columnCount = 0; - int lineIndex = 0; - while ((strLine = sr.ReadLine()) != null) - { - aryLine = strLine.Replace("\"", "").Replace(" ", "").Split(','); - if (lineIndex == 0) - { - columnCount = aryLine.Length; - for (int i = 0; i < columnCount; i++) - { - int typeIndex = i * 2; - int nameIndex = typeIndex + 1; - if (nameIndex < columnCount) - { - DataColumn dc = new DataColumn($"{aryLine[nameIndex]}|{aryLine[typeIndex]}"); - try - { - dt.Columns.Add(dc); - } - catch (Exception ex) - { - ConsoleHelper.WriteErrorLine(ex.ToString()); - return null; - } - } - } - columnCount /= 2; - } - else if (lineIndex == 1) // 注释行 - { - // 注释行先不读,因为注释行里有,号无法分割 - } - else - { - //1,gender1,12.8,TRUE,"[0,0,1]","[[0,0,0],[0,1,0],[0,2,0],[0,4,0]]" - List strs = new List(); - StringBuilder sb = new StringBuilder(); - bool flag = false; - for (int i = 0; i < strLine.Length; i++) - { - if (strLine[i] == '"') - { - flag = !flag; - } - else - { - if (flag || (!flag && strLine[i] != ',')) - { - sb.Append(strLine[i]); - } - else - { - strs.Add(sb.ToString()); - sb.Clear(); - } - } - } - if (sb.Length > 0 || strs.Count < columnCount) - { - strs.Add(sb.ToString()); - sb.Clear(); - } - aryLine = strs.ToArray(); - DataRow dr = dt.NewRow(); - for (int j = 0; j < columnCount; j++) - { - dr[j] = aryLine[j]; - } - dt.Rows.Add(dr); - } - lineIndex++; - } - - sr.Close(); - fs.Close(); - sr.Dispose(); - fs.Dispose(); - return dt; - } - catch (Exception ex) - { - ConsoleHelper.WriteErrorLine(ex.ToString()); - return null; - } - } - - public static bool GenBinaryData(string fileName) - { - try - { - FileInfo fileInfo = new FileInfo(fileName); - var csvName = fileInfo.Name.Remove(fileInfo.Name.IndexOf(".csv")); - - //先写入行数,然后没一行的数据一次写入 小写类型、字符串 - List> datas = new List>(); - var dataTable = CSV2DataTable(fileName); - Tuple rowCount = new Tuple("int", dataTable.Rows.Count.ToString()); - datas.Add(rowCount); - //foreach (var col in dataTable.Columns) - //{ - // ConsoleHelper.WriteInfoLine(col.ToString()); - //} - //for (int i = 0; i < dataTable.Columns.Count; i++) - //{ - // ConsoleHelper.WriteInfoLine(dataTable.Columns[i].ToString()); - //} - foreach (DataRow row in dataTable.Rows) - { - for (int i = 0; i < dataTable.Columns.Count; i++) - { - var typeHeader = dataTable.Columns[i].ToString().ToLower(); - var headers = typeHeader.Split('|'); - Tuple t = new Tuple(headers[1], row[i].ToString()); - datas.Add(t); - } - } - - var binaryFilePath = Path.Combine(fileInfo.DirectoryName, $"{csvName}.bytes"); - FileManager.WriteBinaryDatasToFile(binaryFilePath, datas); - return true; - } - catch (Exception ex) - { - ConsoleHelper.WriteErrorLine(ex.ToString()); - return false; - } - } - - public static string CsvToXlsx(string fileName) - { - try - { - FileInfo fileInfo = new FileInfo(fileName); - var filePath = fileInfo.DirectoryName; - var csvName = fileInfo.Name.Remove(fileInfo.Name.IndexOf(".csv")); - - //加载CSV文件 - Workbook workbook = new Workbook(); - workbook.LoadFromFile(fileName, ",", 1, 1); - - //获取第一个工作表 - Worksheet sheet = workbook.Worksheets[0]; - - //访问工作表中使用的范围 - CellRange usedRange = sheet.AllocatedRange; - //当将范围内的数字保存为文本时,忽略错误 - usedRange.IgnoreErrorOptions = IgnoreErrorType.NumberAsText; - //自适应行高、列宽 - usedRange.AutoFitColumns(); - usedRange.AutoFitRows(); - - var excelPath = Path.Combine(filePath, $"{csvName}.xlsx"); - //保存文档 - workbook.SaveToFile(Path.Combine(filePath, $"{csvName}.xlsx"), ExcelVersion.Version2013); - return excelPath; - } - catch (Exception ex) - { - ConsoleHelper.WriteErrorLine(ex.ToString()); - return null; - } - } - } -} diff --git a/ExcelTool/ExcelHelper.cs b/ExcelTool/ExcelHelper.cs index b372cd8..c9cc6ce 100644 --- a/ExcelTool/ExcelHelper.cs +++ b/ExcelTool/ExcelHelper.cs @@ -9,46 +9,58 @@ namespace ExcelTool { public static class ExcelHelper { - public static List ExcelHeaders(string fileName, out string sheetName, out int sheetCount, int sheetNum = 0) + public static List ParseAllSheets(string fileName) + { + List result = []; + try + { + using FileStream fs = File.OpenRead(fileName); + XSSFWorkbook wk = new(fs); + int sheetCount = wk.NumberOfSheets; + + for (int sheetNum = 0; sheetNum < sheetCount; sheetNum++) + { + ISheet sheet = wk.GetSheetAt(sheetNum); + string sheetName = sheet.SheetName; + + // # 开头的 sheet 跳过 + if (string.IsNullOrEmpty(sheetName) || sheetName.StartsWith('#')) + continue; + + var parsed = ParseSheet(sheet, sheetName); + if (parsed != null) + result.Add(parsed); + } + } + catch (Exception ex) + { + ex.ToString().WriteErrorLine(); + } + return result; + } + + static ParsedSheet ParseSheet(ISheet sheet, string sheetName) { try { - List headers = []; - - using FileStream fs = File.OpenRead(fileName); - XSSFWorkbook wk = new(fs); - - sheetCount = wk.NumberOfSheets; - if (sheetNum >= sheetCount) - { - sheetName = ""; - return null; - } - - ISheet sheet = wk.GetSheetAt(sheetNum); - sheetName = sheet.SheetName; - if (sheetName.StartsWith('#')) - { - return null; - } - - IRow nameRow = sheet.GetRow(0); // 字段名 - IRow typeRow = sheet.GetRow(1); // 类型 - IRow descRow = sheet.GetRow(2); // 注释 + IRow nameRow = sheet.GetRow(0); + IRow typeRow = sheet.GetRow(1); + IRow descRow = sheet.GetRow(2); + var headers = new List(); for (int j = 0; j < nameRow.LastCellNum; j++) { string fieldName = nameRow.GetCell(j)?.ToString() ?? ""; string fieldType = typeRow.GetCell(j)?.ToString() ?? ""; string fieldDesc = descRow.GetCell(j)?.ToString() ?? ""; - + if (string.IsNullOrEmpty(fieldName)) { $"列 {j} 字段名为空".WriteErrorLine(); continue; } - headers.Add(new TableExcelHeader() + headers.Add(new TableExcelHeader { FieldName = fieldName, FieldType = fieldType, @@ -56,60 +68,34 @@ namespace ExcelTool }); } - return headers; - } - catch (Exception ex) - { - ex.ToString().WriteErrorLine(); - sheetName = null; - sheetCount = 0; - return null; - } - } - - public static TableExcelData ExcelData(string fileName, out string sheetName, out int sheetCount, int sheetNum = 0) - { - try - { - var excelHeader = ExcelHeaders(fileName, out sheetName, out sheetCount, sheetNum); + // 数据从第 6 行开始(0-indexed) var tableRows = new List(); - - using FileStream fs = File.OpenRead(fileName); - IWorkbook wk = new XSSFWorkbook(fs); - - if (sheetNum >= sheetCount || sheetName.StartsWith('#')) - { - return null; - } - - ISheet sheet = wk.GetSheetAt(sheetNum); - for (int i = 5; i <= sheet.LastRowNum; i++) { IRow row = sheet.GetRow(i); if (row == null) continue; var tableExcelRow = new TableExcelRow(); - - for (int j = 0; j < excelHeader.Count; j++) - { - var cell = row.GetCell(j); - tableExcelRow.Add(GetCellValue(cell)); - } + for (int j = 0; j < headers.Count; j++) + tableExcelRow.Add(GetCellValue(row.GetCell(j))); tableRows.Add(tableExcelRow); } - return new TableExcelData(excelHeader, tableRows); + return new ParsedSheet + { + SheetName = sheetName, + Headers = headers, + Data = new TableExcelData(headers, tableRows), + }; } catch (Exception ex) { ex.ToString().WriteErrorLine(); - sheetName = null; - sheetCount = 0; return null; } } + private static string GetCellValue(ICell cell) { if (cell == null) @@ -121,11 +107,7 @@ namespace ExcelTool return cell.StringCellValue; case CellType.Numeric: - if (DateUtil.IsCellDateFormatted(cell)) - { - return cell.DateCellValue.ToString(); - } - return cell.NumericCellValue.ToString(); + return DateUtil.IsCellDateFormatted(cell) ? cell.DateCellValue.ToString() : cell.NumericCellValue.ToString(); case CellType.Boolean: return cell.BooleanCellValue ? "1" : "0"; @@ -138,4 +120,11 @@ namespace ExcelTool } } } + + public class ParsedSheet + { + public string SheetName { get; init; } + public List Headers { get; init; } + public TableExcelData Data { get; init; } + } } diff --git a/ExcelTool/FileManager.cs b/ExcelTool/FileManager.cs index 8fffa0e..256c59a 100644 --- a/ExcelTool/FileManager.cs +++ b/ExcelTool/FileManager.cs @@ -10,16 +10,6 @@ namespace ExcelTool /// public static class FileManager { - public static bool CreateDir(string dirPath) - { - if (string.IsNullOrEmpty(dirPath)) - return false; - if (Directory.Exists(dirPath)) - Directory.Delete(dirPath, true); - Directory.CreateDirectory(dirPath); - return true; - } - /// 将数据写入二进制文件(IBinarySerializable 版本) public static bool WriteBinaryDataToFile(string filePath, IBinarySerializable data) { @@ -67,7 +57,7 @@ namespace ExcelTool continue; } - ConsoleHelper.WriteErrorLine($"写入二进制文件:数据类型 \"{rawType}\" 未注册,请在 TypeRegistry 中添加"); + $"写入二进制文件:数据类型 \"{rawType}\" 未注册,请在 TypeRegistry 中添加".WriteErrorLine(); return false; } @@ -76,7 +66,7 @@ namespace ExcelTool } catch (Exception ex) { - ConsoleHelper.WriteErrorLine(ex.ToString()); + ex.ToString().WriteErrorLine(); return false; } } @@ -91,7 +81,7 @@ namespace ExcelTool var elemDesc = TypeRegistry.Get(innerType); if (elemDesc == null) { - ConsoleHelper.WriteErrorLine($"list 的元素类型 \"{innerType}\" 未注册,请在 TypeRegistry 中添加"); + $"list 的元素类型 \"{innerType}\" 未注册,请在 TypeRegistry 中添加".WriteErrorLine(); return; } @@ -140,7 +130,7 @@ namespace ExcelTool } public static bool WriteToFile(string filePath, string context) => - WriteToFile(filePath, context, Encoding.Default); + WriteToFile(filePath, context, new UTF8Encoding(false)); public static bool WriteToFile(string filePath, string context, Encoding encoding) { diff --git a/ExcelTool/Parser/GenModels.cs b/ExcelTool/Parser/GenModels.cs index d46d17e..9d22997 100644 --- a/ExcelTool/Parser/GenModels.cs +++ b/ExcelTool/Parser/GenModels.cs @@ -10,53 +10,39 @@ namespace ExcelTool.Parser /// /// 生成对应的 C# Model 类 /// - public static bool GenCSharpModel(string fileName, string outputDir, string nameSpace = "") + public static bool GenCSharpModel(List parsedSheets, string outputDir, string nameSpace = "") { - if (string.IsNullOrEmpty(fileName)) - { - "GenCSharpModel 参数传递有误".WriteErrorLine(); - return false; - } - try { - FileInfo fileInfo = new(fileName); - if (string.IsNullOrEmpty(outputDir)) - outputDir = fileInfo.DirectoryName; - - for (int sheetNum = 0; ; sheetNum++) + foreach(ParsedSheet sheet in parsedSheets) { - var headers = ExcelHelper.ExcelHeaders(fileName, out string sheetName, out int sheetCount, sheetNum); - if (headers == null || headers.Count == 0 || sheetName.StartsWith("#") || sheetNum > sheetCount) - break; - - var sb = new StringBuilder(); - sb.Append($"/*\n * auto generated by tools(注意:千万不要手动修改本文件)\n * {sheetName}\n */\n"); - sb.Append("using System;\nusing System.IO;\nusing System.Collections.Generic;\nusing System.Text;\nusing WKMobile.Generated;\n\n"); + StringBuilder sb = new(); + sb.Append($"/*\n * auto generated by tools(注意:千万不要手动修改本文件)\n * {sheet.SheetName}\n */\n"); + sb.Append("using System;\nusing System.IO;\nusing System.Collections.Generic;\nusing System.Text;\n\n"); if (!string.IsNullOrEmpty(nameSpace)) sb.Append($"namespace {nameSpace}\n{{\n"); // ── 数据行类 ───────────────────────────────────────────────── sb.Append("[Serializable]\n"); - sb.Append($"public partial class {sheetName} : IBinarySerializable\n"); + sb.Append($"public partial class {sheet.SheetName} : IBinarySerializable\n"); sb.Append("{\n"); - foreach (var header in headers) + foreach (var header in sheet.Headers) AppendProperty(sb, header); - AppendDeserializeMethod(sb, headers, sheetName); - AppendSerializeMethod(sb, headers, sheetName); + AppendDeserializeMethod(sb, sheet.Headers, sheet.SheetName); + AppendSerializeMethod(sb, sheet.Headers, sheet.SheetName); sb.Append("}\n\n"); // ── Config 容器类 ───────────────────────────────────────────── - AppendConfigClass(sb, sheetName); + AppendConfigClass(sb, sheet.SheetName); if (!string.IsNullOrEmpty(nameSpace)) sb.Append("}\n"); - FileManager.WriteToFile(Path.Combine(outputDir, $"{sheetName}.cs"), sb.ToString()); + FileManager.WriteToFile(Path.Combine(outputDir, $"{sheet.SheetName}.cs"), sb.ToString()); } return true; @@ -234,16 +220,9 @@ namespace ExcelTool.Parser } /// 从 TypeDescriptor 反推 reader.ReadXxx() 表达式(用于 list<T> 代码生成) - private static string GetReadExpr(TypeDescriptor desc) + static string GetReadExpr(TypeDescriptor desc) { - // GenDeserialize 生成的行形如 "\t\tname = reader.ReadXxx();\n" - // 这里简单地从注册表拿一个占位 name 然后截取表达式部分 - const string placeholder = "__x__"; - var line = desc.GenDeserialize(placeholder).Trim(); // "x = reader.ReadXxx();" - var eqIdx = line.IndexOf('='); - return eqIdx >= 0 - ? line[(eqIdx + 1)..].TrimEnd(';').Trim() // "reader.ReadXxx()" - : $"/* unknown read for {desc.TypeName} */"; + return desc.ReadExpression ?? $"/* unknown read for {desc.TypeName} */"; } } } diff --git a/ExcelTool/Parser/TableExcelExportBytes.cs b/ExcelTool/Parser/TableExcelExportBytes.cs index 2f1d247..4aba69b 100644 --- a/ExcelTool/Parser/TableExcelExportBytes.cs +++ b/ExcelTool/Parser/TableExcelExportBytes.cs @@ -6,35 +6,21 @@ namespace ExcelTool.Parser { public static class TableExcelExportBytes { - public static bool ExportToFile(string fileName, string outputDir = null) + public static bool ExportToFile(List parsedSheets, string outputDir = null) { try { - FileInfo fileInfo = new(fileName); - if (string.IsNullOrEmpty(outputDir)) + foreach(ParsedSheet sheet in parsedSheets) { - outputDir = fileInfo.DirectoryName; - } - - for (int sheetNum = 0; ; sheetNum++) - { - var tableData = ExcelHelper.ExcelData(fileName, out string sheetName, out int sheetCount, sheetNum); - if (tableData == null || sheetNum >= sheetCount) - break; - - // # 开头的 sheet 只跳过 - if (sheetName.StartsWith("#")) - continue; - List> datas = []; //先写入行数,然后每一行的数据一次写入 小写类型、字符串 - Tuple rowCount = new("int", tableData.RowCounts.ToString()); + Tuple rowCount = new("int", sheet.Data.RowCounts.ToString()); datas.Add(rowCount); - foreach (var row in tableData.Rows) + foreach (var row in sheet.Data.Rows) { - for (int i = 0; i < tableData.CollonCount; i++) + for (int i = 0; i < sheet.Data.CollonCount; i++) { - var type = tableData.Headers[i].FieldType.ToLower(); + var type = sheet.Data.Headers[i].FieldType.ToLower(); var data = row.StrList[i]; // 未在 TypeRegistry 注册的类型(且不是 list)当枚举处理,写入 byte @@ -46,7 +32,7 @@ namespace ExcelTool.Parser datas.Add(new Tuple(type, data)); } } - var binaryFilePath = Path.Combine(outputDir, $"{sheetName}.bytes"); + var binaryFilePath = Path.Combine(outputDir, $"{sheet.SheetName}.bytes"); FileManager.WriteBinaryDatasToFile(binaryFilePath, datas); } return true; @@ -59,6 +45,6 @@ namespace ExcelTool.Parser } private static bool IsGenericList(string type) => - type.StartsWith("list<") && type.EndsWith(">"); + type.StartsWith("list<") && type.EndsWith('>'); } } diff --git a/ExcelTool/Program.cs b/ExcelTool/Program.cs index aa1c806..d506159 100644 --- a/ExcelTool/Program.cs +++ b/ExcelTool/Program.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using ExcelTool.Parser; namespace ExcelTool @@ -46,45 +45,32 @@ namespace ExcelTool { outputDataDir = outputCodeDir; } - + // TODO 使用System.CommandLine重构参数解析 DirectoryInfo dirInfo = new(path); - FileInfo[] csvs = dirInfo.GetFiles("*.csv", SearchOption.AllDirectories); FileInfo[] excels = dirInfo.GetFiles("*.xlsx", SearchOption.AllDirectories); - if ((csvs.Length <= 0) && (excels.Length <= 0)) + if (excels.Length <= 0) { - "当前exe目录或者目标目录没有csv文件或者excels文件,请重新设置目录".WriteErrorLine(); + "当前exe目录或者目标目录没有excels文件,请重新设置目录".WriteErrorLine(); } else { "==========================================================".WriteSuccessLine(); - "== 根据csv/xlsx生成模板代码和二进制文件工具 ==".WriteSuccessLine(); - "== 说明:将exe放在csv/xlsx目录中或者exe或者传入csv根目录 ==".WriteSuccessLine(); + "== 根据xlsx生成模板代码和二进制文件工具 ==".WriteSuccessLine(); + "== 说明:将exe放在xlsx目录中或者exe或者传入根目录 ==".WriteSuccessLine(); "==========================================================".WriteSuccessLine(); - List genExcels = []; - foreach (FileInfo csv in csvs) - { - //生成对应的xlsx文件 - var tempPath = CsvHelper.CsvToXlsx(csv.FullName); - if (string.IsNullOrEmpty(tempPath)) - { - $"csv:{csv.FullName}生成xlsx文件出错".WriteErrorLine(); - } - else - { - genExcels.Add(tempPath); - } - } excels = dirInfo.GetFiles("*.xlsx", SearchOption.AllDirectories); //读取 - foreach (var file in excels) + foreach (FileInfo file in excels) { - if (file.Name.StartsWith("~$")) return; + if (file.Name.StartsWith("~$")) continue; + + List sheets = ExcelHelper.ParseAllSheets(file.FullName); //生成CS文件 - bool res = GenModels.GenCSharpModel(file.FullName, outputCodeDir, nameSpace); + bool res = GenModels.GenCSharpModel(sheets, outputCodeDir, nameSpace); if (res) { $"{file.Name}CS模板生成成功".WriteSuccessLine(); @@ -95,7 +81,7 @@ namespace ExcelTool } //生成二进制文件,如果list或者vector数据为空则写入0,要根据类型来读取csv的字段数据强转成对应的数据类型然后写入 - res = TableExcelExportBytes.ExportToFile(file.FullName, outputDataDir); + res = TableExcelExportBytes.ExportToFile(sheets, outputDataDir); if (res) { $"{file.Name}二进制数据生成成功".WriteSuccessLine(); @@ -105,17 +91,10 @@ namespace ExcelTool $"{file.Name}二进制数据生成失败".WriteErrorLine(); } } + + // TODO 抽象 ExcelProcess 类 处理相关流程 - //删除生成的excels - for (int i = genExcels.Count - 1; i >= 0; i--) - { - File.Delete(genExcels[i]); - } - - Dictionary dics = new(); - new List(dics.Values); - - //读取测试 + // TODO 单元测试 //IBinarySerializable newavList = new avatarguideTestConfig(); //var readOK = FileManager.ReadBinaryDataFromFile(Path.Combine(path, "avatarguideTest.bytes"), ref newavList); //if (readOK) diff --git a/ExcelTool/TypeRegistry.cs b/ExcelTool/TypeRegistry.cs index 30c096f..0119b61 100644 --- a/ExcelTool/TypeRegistry.cs +++ b/ExcelTool/TypeRegistry.cs @@ -29,6 +29,9 @@ namespace ExcelTool /// 生成 Serialize 方法体片段(变量名 → 代码行) /// public Func GenSerialize { get; init; } + + /// 用于代码生成的单次读取表达式,例如 "reader.ReadInt32()" + public string ReadExpression { get; init; } } /// @@ -158,6 +161,7 @@ namespace ExcelTool { TypeName = typeName, CSharpType = csType, + ReadExpression = readExpr, WriteBinary = writeBinary, GenDeserialize = name => $"\t\t{name} = {readExpr};\n", GenSerialize = name => $"\t\twriter.Write({name});\n", @@ -194,7 +198,7 @@ namespace ExcelTool /// 生成 List<T> 的 DeSerialize 片段 public static string GenListDeserialize(string name, string elemCsType, string readElemExpr) { - var camel = StringExtensions.ToCamelCase(name); + string camel = name.ToCamelCase(); return $"\t\tvar {camel}Count = reader.ReadInt32();\n" + $"\t\tif ({camel}Count > 0)\n" + @@ -231,7 +235,7 @@ namespace ExcelTool private static string GenVectorListDeserialize(string name) { - var camel = StringExtensions.ToCamelCase(name); + string camel = name.ToCamelCase(); return $"\t\tvar {camel}Count = reader.ReadInt32();\n" + $"\t\tif ({camel}Count > 0)\n" +