diff --git a/Config/Excel/BaitConfig.xlsx b/Config/Excel/BaitConfig.xlsx index b01335f..1f100b9 100644 Binary files a/Config/Excel/BaitConfig.xlsx and b/Config/Excel/BaitConfig.xlsx differ diff --git a/Config/Excel/UnitConfig.xlsx b/Config/Excel/UnitConfig.xlsx index 8a94590..4cb4ee5 100644 Binary files a/Config/Excel/UnitConfig.xlsx and b/Config/Excel/UnitConfig.xlsx differ diff --git a/Config/Excel/~$UnitConfig.xlsx b/Config/Excel/~$UnitConfig.xlsx new file mode 100644 index 0000000..036bba4 Binary files /dev/null and b/Config/Excel/~$UnitConfig.xlsx differ diff --git a/Tools/ConfigBuilder/ConfigBuilder.sln.DotSettings.user b/Tools/ConfigBuilder/ConfigBuilder.sln.DotSettings.user index bc0585f..d5915f5 100644 --- a/Tools/ConfigBuilder/ConfigBuilder.sln.DotSettings.user +++ b/Tools/ConfigBuilder/ConfigBuilder.sln.DotSettings.user @@ -1,3 +1,6 @@  + ForceIncluded + ForceIncluded ForceIncluded - ForceIncluded \ No newline at end of file + ForceIncluded + ForceIncluded \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelExporter.cs b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelExporter.cs index b021e9f..fc0e943 100644 --- a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelExporter.cs +++ b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelExporter.cs @@ -21,27 +21,14 @@ public sealed class ExcelExporter public ExportType ExportType; private readonly string _excelProgramPath; private readonly string _versionFilePath; - - // private readonly string _excelClientFileDirectory; - // private readonly string _excelServerFileDirectory; - // private readonly string _excelServerJsonDirectory; - // private readonly string _excelClientJsonDirectory; - - public VersionInfo VersionInfo; // 存储 Excel 文件的版本信息。 + + // public VersionInfo VersionInfo; // 存储 Excel 文件的版本信息。 private readonly Regex _regexName = new Regex("^[a-zA-Z][a-zA-Z0-9_]*$"); // 用于验证 Excel 表名的正则表达式。 private readonly HashSet _loadFiles = [".xlsx", ".xlsm", ".csv"]; // 加载的支持文件扩展名。 - - private readonly OneToManyList - _tables = new OneToManyList(); // 存储 Excel 表及其导出信息。 - + private readonly ConcurrentDictionary _excelTables = new ConcurrentDictionary(); // 存储解析后的 Excel 表。 - - public readonly ConcurrentDictionary Worksheets = - new ConcurrentDictionary(); // 存储已加载的 Excel 工作表。 - - public readonly Dictionary IgnoreTable = new Dictionary(); // 存储以#开头的的表和路径 - + /// /// 导表支持的数据类型集合。 /// @@ -52,6 +39,9 @@ public sealed class ExcelExporter "short[]", "int[]", "long[]", "float[]", "string[]", "uint[]" ]; + // 进度报告回调 + private Action _progressCallback; + static ExcelExporter() { ExcelPackage.License.SetNonCommercialOrganization("Fantasy"); @@ -130,16 +120,31 @@ public sealed class ExcelExporter break; } } + } - // SerializerManager.Initialize(); + /// + /// 设置进度报告回调 + /// + /// 进度报告回调函数 + public void SetProgressCallback(Action callback) + { + _progressCallback = callback; } public void Run() { + ReportProgress("正在查找配置文件..."); Find(); + ReportProgress("正在解析配置表..."); Parsing(); - ExportToBinary(); - File.WriteAllText(_versionFilePath, JsonConvert.SerializeObject(VersionInfo)); + ReportProgress("正在导出JSON数据..."); + ExportToJson(); + ReportProgress("导出完成"); + } + + private void ReportProgress(string message) + { + _progressCallback?.Invoke(message); } /// @@ -147,10 +152,6 @@ public sealed class ExcelExporter /// private void Find() { - VersionInfo = File.Exists(_versionFilePath) - ? JsonConvert.DeserializeObject(File.ReadAllText(_versionFilePath)) - : new VersionInfo(); - var dir = new DirectoryInfo(_excelProgramPath); var excelFiles = dir.GetFiles("*", SearchOption.AllDirectories); @@ -159,6 +160,10 @@ public sealed class ExcelExporter return; } + + var tables = new List(); + + // var tables = new OneToManyList(); foreach (var excelFile in excelFiles) { // 过滤掉非指定后缀的文件 @@ -187,15 +192,12 @@ public sealed class ExcelExporter } // 如果文件名以#开头,那么这个文件夹下的所有文件都不导出 - if (excelName.StartsWith("#", StringComparison.Ordinal)) { - IgnoreTable.Add(excelName, fullName); continue; } // 如果文件夹名包含#,那么这个文件夹下的所有文件都不导出 - if (path.Contains("#", StringComparison.Ordinal)) { continue; @@ -207,79 +209,31 @@ public sealed class ExcelExporter continue; } - var exportInfo = new ExportInfo() - { - Name = excelName, FileInfo = excelFile - }; - - _tables.Add(excelName.Split('_')[0], exportInfo); + tables.Add(excelFile); } - var removeTables = new List(); - foreach (var (tableName, tableList) in _tables) - { - var isNeedExport = false; - - foreach (var exportInfo in tableList) - { - var key = HashCodeHelper.ComputeHash64(exportInfo.Name); - var timer = TimeHelper.Transition(exportInfo.FileInfo.LastWriteTime); - - if (!isNeedExport) - { - if (VersionInfo.Tables.TryGetValue(key, out var lastWriteTime)) - { - isNeedExport = lastWriteTime != timer; - } - else - { - isNeedExport = true; - } - } - - VersionInfo.Tables[key] = timer; - } - - if (!isNeedExport) - { - removeTables.Add(tableName); - } - } - - foreach (var removeTable in removeTables) - { - _tables.Remove(removeTable); - } - - foreach (var (_, exportInfo) in _tables) - { - exportInfo.Sort((x, y) => Compare(x.Name, y.Name, StringComparison.Ordinal)); - } - } - - /// - /// 生成配置文件 - /// - private void Parsing() - { var generateTasks = new List(); - foreach (var (tableName, tableList) in _tables) + foreach (var table in tables) { var task = Task.Run(() => { - var writeToClassTask = new List(); - var excelTable = new ExcelTable(tableName); - - // 筛选需要导出的列 - foreach (var exportInfo in tableList) + var worksheets = LoadExcel(table.FullName); + foreach (var worksheet in worksheets) { + var tableName = worksheet.Name; + if (tableName.Contains("#", StringComparison.Ordinal)) + { + continue; + } + + ReportProgress($"正在解析配置表: {table.Name} Sheet:{tableName}"); + var excelTable = new ExcelTable(worksheet); try { var serverColInfoList = new List(); var clientColInfoList = new List(); - var worksheet = LoadExcel(exportInfo.FileInfo.FullName, true); for (var col = 3; col <= worksheet.Columns.EndColumn; col++) { @@ -312,20 +266,20 @@ public sealed class ExcelExporter if (isExportServer && isExportClient & serverType != clientType) { Log.Info( - $"配置表 {exportInfo.Name} {col} 列 [{colName}] 客户端类型 {clientType} 和 服务端类型 {serverType} 不一致"); + $"配置表 {tableName} {col} 列 [{colName}] 客户端类型 {clientType} 和 服务端类型 {serverType} 不一致"); continue; } if (!ColTypeSet.Contains(serverType) || !ColTypeSet.Contains(clientType)) { Log.Info( - $"配置表 {exportInfo.Name} {col} 列 [{colName}] 客户端类型 {clientType}, 服务端类型 {serverType} 不合法"); + $"配置表 {tableName} {col} 列 [{colName}] 客户端类型 {clientType}, 服务端类型 {serverType} 不合法"); continue; } if (!_regexName.IsMatch(colName)) { - Log.Info($"配置表 {exportInfo.Name} {col} 列 [{colName}] 列名非法"); + Log.Info($"配置表 {tableName} {col} 列 [{colName}] 列名非法"); continue; } @@ -339,320 +293,355 @@ public sealed class ExcelExporter if (clientColInfoList.Count > 0) { - excelTable.ClientColInfos.Add(exportInfo.FileInfo.FullName, clientColInfoList); + excelTable.ClientColInfos.Add(tableName, clientColInfoList); } if (serverColInfoList.Count > 0) { - excelTable.ServerColInfos.Add(exportInfo.FileInfo.FullName, serverColInfoList); + excelTable.ServerColInfos.Add(tableName, serverColInfoList); } } catch (Exception e) { - Log.Error($"Config : {tableName}, Name : {exportInfo.Name}, Error : {e}"); + Log.Error($"Config : {tableName}, Name : {tableName}, Error : {e}"); } + + _excelTables.TryAdd(tableName, excelTable); } - - // 生成cs文件 - - if (App.Config.GenServer) - { - writeToClassTask.Add(Task.Run(() => - { - WriteToClass(excelTable.ServerColInfos, App.Config.ServerPath, true); - })); - } - - if (App.Config.GenClient) - { - writeToClassTask.Add(Task.Run(() => - { - WriteToClass(excelTable.ClientColInfos, App.Config.ClientPath, false); - })); - } - - Task.WaitAll(writeToClassTask.ToArray()); - _excelTables.TryAdd(tableName, excelTable); }); generateTasks.Add(task); } Task.WaitAll(generateTasks.ToArray()); - Console.WriteLine("build success==="); } /// - /// 把数据和实体类转换二进制导出到文件中 + /// 生成配置文件 /// - private void ExportToBinary() + private void Parsing() { - System.Reflection.Assembly dynamicServerAssembly = null; - System.Reflection.Assembly dynamicClientAssembly = null; - var exportToBinaryTasks = new List(); + var generateTasks = new List(); - if (App.Config.GenServer && - Directory.Exists(App.Config.ServerPath)) - { - dynamicServerAssembly = DynamicAssembly.Load(App.Config.ServerPath); - } - - if (App.Config.GenClient && - Directory.Exists(App.Config.ClientPath)) - { - dynamicClientAssembly = DynamicAssembly.Load(App.Config.ClientPath); - } - - foreach (var (tableName, tableList) in _tables) + foreach ((var tableName, ExcelTable excelTable) in _excelTables) { var task = Task.Run(() => { - DynamicConfigDataType serverDynamicInfo = null; - DynamicConfigDataType clientDynamicInfo = null; - - var idCheck = new HashSet(); - var excelTable = _excelTables[tableName]; - var csName = Path.GetFileNameWithoutExtension(tableName); + // 生成cs文件 + var writeToClassTask = new List(); + var table = excelTable; if (App.Config.GenServer) { - var serverColInfoCount = excelTable.ServerColInfos.Sum(d => d.Value.Count); - serverDynamicInfo = serverColInfoCount == 0 - ? null - : DynamicAssembly.GetDynamicInfo(dynamicServerAssembly, csName); + writeToClassTask.Add(Task.Run(() => + { + ReportProgress($"正在生成服务端CS文件: {tableName}"); + WriteToClass(table, true); + })); } if (App.Config.GenClient) { - var clientColInfoCount = excelTable.ClientColInfos.Sum(d => d.Value.Count); - clientDynamicInfo = clientColInfoCount == 0 - ? null - : DynamicAssembly.GetDynamicInfo(dynamicClientAssembly, csName); + writeToClassTask.Add(Task.Run(() => + { + ReportProgress($"正在生成客户端CS文件: {tableName}"); + WriteToClass(table, false); + })); } - for (var i = 0; i < tableList.Count; i++) - { - var tableListName = tableList[i]; - - try - { - var fileInfoFullName = tableListName.FileInfo.FullName; - var excelWorksheet = LoadExcel(fileInfoFullName, false); - var rows = excelWorksheet.Dimension.Rows; - excelTable.ServerColInfos.TryGetValue(fileInfoFullName, out var serverCols); - excelTable.ClientColInfos.TryGetValue(fileInfoFullName, out var clientCols); - - for (var row = 7; row <= rows; row++) - { - if (excelWorksheet.GetCellValue(row, 1).StartsWith("#", StringComparison.Ordinal)) - { - continue; - } - - var id = excelWorksheet.GetCellValue(row, 3); - - if (idCheck.Contains(id)) - { - Log.Info($"{tableListName.Name} 存在重复Id {id} 行号 {row}"); - continue; - } - - idCheck.Add(id); - var isLast = row == rows && (i == tableList.Count - 1); - - if (App.Config.GenServer) - { - GenerateBinary(fileInfoFullName, excelWorksheet, serverDynamicInfo, serverCols, id, row, - isLast, true); - } - - if (App.Config.GenClient) - { - GenerateBinary(fileInfoFullName, excelWorksheet, clientDynamicInfo, clientCols, id, row, - isLast, false); - } - } - } - catch (Exception e) - { - Log.Error($"Table:{tableListName} error! \n{e}"); - throw; - } - } - - if (serverDynamicInfo?.ConfigData != null) - { - // var memoryStream = new MemoryStreamBuffer(); - // SerializerManager.GetSerializer(FantasySerializerType.ProtoBuf) - // .Serialize(serverDynamicInfo.ConfigData, memoryStream); - // if (!Directory.Exists(_excelServerBinaryDirectory)) - // { - // Directory.CreateDirectory(_excelServerBinaryDirectory); - // } - - // var asSpan = memoryStream.GetBuffer().AsSpan(0, (int)memoryStream.Position); - // File.WriteAllBytes(Path.Combine(_excelServerBinaryDirectory, $"{csName}Data.bytes"), - // asSpan.ToArray()); - - if (serverDynamicInfo.Json.Length > 0) - { - if (!Directory.Exists(App.Config.ServerJsonPath)) - { - Directory.CreateDirectory(App.Config.ServerJsonPath); - } - - using var sw = new StreamWriter(Path.Combine(App.Config.ServerJsonPath, $"{csName}Data.Json")); - sw.WriteLine("{\"List\":["); - sw.Write(serverDynamicInfo.Json.ToString()); - sw.WriteLine("]}"); - } - } - - if (clientDynamicInfo?.ConfigData != null) - { - // var memoryStream = new MemoryStreamBuffer(); - // SerializerManager.GetSerializer(FantasySerializerType.ProtoBuf) - // .Serialize(clientDynamicInfo.ConfigData, memoryStream); - // if (!Directory.Exists(_excelClientBinaryDirectory)) - // { - // Directory.CreateDirectory(_excelClientBinaryDirectory); - // } - // - // var asSpan = memoryStream.GetBuffer().AsSpan(0, (int)memoryStream.Position); - // File.WriteAllBytes(Path.Combine(_excelClientBinaryDirectory, $"{csName}Data.bytes"), - // asSpan.ToArray()); - - if (clientDynamicInfo.Json.Length > 0) - { - if (!Directory.Exists(App.Config.ClientJsonPath)) - { - Directory.CreateDirectory(App.Config.ClientJsonPath); - } - - using var sw = new StreamWriter(Path.Combine(App.Config.ClientJsonPath, $"{csName}Data.Json")); - sw.WriteLine("{\"List\":["); - sw.Write(clientDynamicInfo.Json.ToString()); - sw.WriteLine("]}"); - } - } + Task.WaitAll(writeToClassTask.ToArray()); }); - exportToBinaryTasks.Add(task); + + generateTasks.Add(task); } - Task.WaitAll(exportToBinaryTasks.ToArray()); + Task.WaitAll(generateTasks.ToArray()); + Console.WriteLine("build cs success==="); } - private void GenerateBinary(string fileInfoFullName, ExcelWorksheet excelWorksheet, - DynamicConfigDataType dynamicInfo, List cols, string id, int row, bool isLast, bool isServer) + #region json + + private Dictionary>> _clientTableJsonDictionary = + new Dictionary>>(); + + private Dictionary>> _serverTableJsonDictionary = + new Dictionary>>(); + + /// + /// 把数据生成json + /// + private void ExportToJson() { - if (cols == null || IsNullOrEmpty(id) || cols.Count <= 0 || dynamicInfo?.ConfigType == null) + _clientTableJsonDictionary.Clear(); + _serverTableJsonDictionary.Clear(); + foreach (var (tableName, excelTable) in _excelTables) { - return; - } - - var config = DynamicAssembly.CreateInstance(dynamicInfo.ConfigType); - - for (var i = 0; i < cols.Count; i++) - { - string colType; - var colIndex = cols[i]; - var colName = excelWorksheet.GetCellValue(5, colIndex); - var value = excelWorksheet.GetCellValue(row, colIndex); - - if (isServer) + // 示例:客户端JSON导出 + if (App.Config.GenClient && excelTable.ClientColInfos.Count > 0) { - colType = excelWorksheet.GetCellValue(1, colIndex); - - if (IsNullOrEmpty(colType) || colType == "0") - { - colType = excelWorksheet.GetCellValue(2, colIndex); - } - } - else - { - colType = excelWorksheet.GetCellValue(2, colIndex); + ReportProgress($"正在生成客户端JSON文件: {tableName}"); + ExportTableToJson(excelTable, excelTable.ClientColInfos, _clientTableJsonDictionary); } - try + // 示例:服务端JSON导出 + if (App.Config.GenServer && excelTable.ServerColInfos.Count > 0) { - SetNewValue(dynamicInfo.ConfigType.GetProperty(colName), config, colType, value); - } - catch (Exception e) - { - Log.Error( - $"Error Table {fileInfoFullName} Col:{colName} colType:{colType} Row:{row} value:{value} {e}"); - throw; + ReportProgress($"正在生成服务端JSON文件: {tableName}"); + ExportTableToJson(excelTable, excelTable.ServerColInfos, _serverTableJsonDictionary); } } - dynamicInfo.Method.Invoke(dynamicInfo.Obj, new object[] { config }); - - var json = JsonConvert.SerializeObject(config); - - if (isLast) + if (_clientTableJsonDictionary.Count > 0) { - dynamicInfo.Json.AppendLine(json); + ReportProgress("正在写入客户端JSON文件: configs.json"); + var json = JsonConvert.SerializeObject(_clientTableJsonDictionary, Formatting.Indented); + File.WriteAllText(Path.Combine(App.Config.ClientJsonPath, $"configs.json"), json); } - else + + if (_serverTableJsonDictionary.Count > 0) { - dynamicInfo.Json.AppendLine($"{json},"); + ReportProgress("正在写入服务端JSON文件: configs.json"); + var json = JsonConvert.SerializeObject(_serverTableJsonDictionary, Formatting.Indented); + File.WriteAllText(Path.Combine(App.Config.ServerJsonPath, $"configs.json"), json); } } + private void ExportTableToJson(ExcelTable table, TableDictionary colInfos, + Dictionary>> dictionary) + { + var result = new List>(); + + var worksheet = table.Sheet; + foreach (var (fileName, columns) in colInfos) + { + // 从第7行开始读取数据(前6行为表头) + for (int row = 7; row <= worksheet.Rows.EndRow; row++) + { + // 检查是否为空行 + bool isEmptyRow = true; + foreach (var col in columns) + { + var cellValue = worksheet.GetCellValue(row, col); + if (!IsNullOrEmpty(cellValue)) + { + isEmptyRow = false; + break; + } + } + + // 如果整行都为空,则停止处理 + if (isEmptyRow) + { + break; + } + + var rowData = new Dictionary(); + + foreach (var col in columns) + { + var columnName = worksheet.GetCellValue(5, col); + var cellValue = worksheet.GetCellValue(row, col); + // 可在此处做类型转换 + var columnType = GetColumnType(worksheet, col); // 需要实现获取列类型的方法 + rowData[columnName] = ConvertCellValue(cellValue, columnType); + } + + result.Add(rowData); + } + } + + dictionary[table.Name] = result; + } + + private string GetColumnType(ExcelWorksheet worksheet, int column) + { + var serverType = worksheet.GetCellValue(1, column); + var clientType = worksheet.GetCellValue(2, column); + + // 根据实际情况确定使用哪个类型,这里简化处理 + return !string.IsNullOrEmpty(serverType) && serverType != "0" ? serverType : clientType; + } + + private object ConvertCellValue(string cellValue, string targetType) + { + if (string.IsNullOrEmpty(cellValue)) + { + // 返回默认值 + if (targetType.EndsWith("[]")) + { + var elementType = targetType.Substring(0, targetType.Length - 2); + return Array.CreateInstance(Type.GetType(elementType) ?? typeof(object), 0); + } + + return GetDefaultValue(targetType); + } + + // 处理数组类型 + if (targetType.EndsWith("[]")) + { + var elementType = targetType.Substring(0, targetType.Length - 2); + var values = cellValue.Split(','); + + switch (elementType) + { + case "short": + return values.Select(v => + { + short result; + return short.TryParse(v, out result) ? result : (short)0; + }).ToArray(); + + case "ushort": + return values.Select(v => + { + ushort result; + return ushort.TryParse(v, out result) ? result : (ushort)0; + }).ToArray(); + + case "int": + return values.Select(v => + { + int result; + return int.TryParse(v, out result) ? result : 0; + }).ToArray(); + + case "uint": + return values.Select(v => + { + uint result; + return uint.TryParse(v, out result) ? result : 0u; + }).ToArray(); + + case "long": + return values.Select(v => + { + long result; + return long.TryParse(v, out result) ? result : 0L; + }).ToArray(); + + case "ulong": + return values.Select(v => + { + ulong result; + return ulong.TryParse(v, out result) ? result : 0UL; + }).ToArray(); + + case "bool": + return values.Select(v => + { + bool result; + return bool.TryParse(v, out result) ? result : false; + }).ToArray(); + + case "string": + return values.Select(v => v.Trim()).ToArray(); + + default: + return values; + } + } + + // 处理单个值 + switch (targetType) + { + case "short": + short shortResult; + return short.TryParse(cellValue, out shortResult) ? shortResult : (short)0; + + case "ushort": + ushort ushortResult; + return ushort.TryParse(cellValue, out ushortResult) ? ushortResult : (ushort)0; + + case "int": + int intResult; + return int.TryParse(cellValue, out intResult) ? intResult : 0; + + case "uint": + uint uintResult; + return uint.TryParse(cellValue, out uintResult) ? uintResult : 0u; + + case "long": + long longResult; + return long.TryParse(cellValue, out longResult) ? longResult : 0L; + + case "ulong": + ulong ulongResult; + return ulong.TryParse(cellValue, out ulongResult) ? ulongResult : 0UL; + + case "bool": + bool boolResult; + if (bool.TryParse(cellValue, out boolResult)) + { + return boolResult; + } + else + { + int numericBool; + return int.TryParse(cellValue, out numericBool) ? numericBool != 0 : false; + } + + case "string": + return cellValue; + + default: + return cellValue; + } + } + + private object GetDefaultValue(string type) + { + switch (type) + { + case "short": return (short)0; + case "ushort": return (ushort)0; + case "int": return 0; + case "uint": return 0u; + case "long": return 0L; + case "ulong": return 0UL; + case "bool": return false; + case "string": return ""; + case "short[]": return new short[0]; + case "ushort[]": return new ushort[0]; + case "int[]": return new int[0]; + case "uint[]": return new uint[0]; + case "long[]": return new long[0]; + case "ulong[]": return new ulong[0]; + case "bool[]": return new bool[0]; + case "string[]": return new string[0]; + default: return null; + } + } + + #endregion /// /// 从 Excel 文件加载工作表并返回 ExcelWorksheet 对象。 /// /// 工作表的名称或文件路径。 - /// 是否将加载的工作表添加到缓存字典中。 /// 表示 Excel 工作表的 ExcelWorksheet 对象。 - public ExcelWorksheet LoadExcel(string name, bool isAddToDic) + public List LoadExcel(string name) { - if (Worksheets.TryGetValue(name, out var worksheet)) - { - return worksheet; - } - var workbookWorksheets = ExcelHelper.LoadExcel(name).Workbook.Worksheets; - worksheet = workbookWorksheets[0]; - - if (isAddToDic) - { - Worksheets.TryAdd(name, worksheet); - - foreach (var workbookWorksheet in workbookWorksheets) - { - try - { - var hash = HashCodeHelper.ComputeHash64(workbookWorksheet.Name); - VersionInfo.WorksheetNames.Add(hash); - } - catch (Exception e) - { - Console.WriteLine(e); - } - - Worksheets.TryAdd(workbookWorksheet.Name, workbookWorksheet); - } - } - - Log.Info(name); - return workbookWorksheets[0]; + return workbookWorksheets.ToList(); } /// /// 写入到cs /// - /// - /// + /// /// - private void WriteToClass(TableDictionary colInfos, string exportPath, bool isServer) + private void WriteToClass(ExcelTable table, bool isServer) { + var colInfos = isServer ? table.ServerColInfos : table.ClientColInfos; + var exportPath = isServer ? App.Config.ServerPath : App.Config.ClientPath; + if (colInfos.Count <= 0) { return; } + var excelWorksheet = table.Sheet; + var index = 0; var fileBuilder = new StringBuilder(); var colNameSet = new HashSet(); @@ -671,19 +660,16 @@ public sealed class ExcelExporter continue; } - var excelWorksheet = LoadExcel(tableName, false); foreach (var colIndex in cols) { var colName = excelWorksheet.GetCellValue(5, colIndex); - if (colNameSet.Contains(colName)) + if (!colNameSet.Add(colName)) { continue; } - colNameSet.Add(colName); - string colType; if (isServer) @@ -744,197 +730,6 @@ public sealed class ExcelExporter } } - private void SetNewValue(PropertyInfo propertyInfo, object config, string type, string value) - { - if (IsNullOrWhiteSpace(value)) - { - return; - } - - switch (type) - { - case "short": - { - propertyInfo.SetValue(config, Convert.ToInt16(value)); - return; - } - case "ushort": - { - propertyInfo.SetValue(config, Convert.ToUInt16(value)); - return; - } - case "uint": - { - propertyInfo.SetValue(config, Convert.ToUInt32(value)); - return; - } - case "int": - { - propertyInfo.SetValue(config, Convert.ToInt32(value)); - return; - } - case "decimal": - { - propertyInfo.SetValue(config, Convert.ToDecimal(value)); - return; - } - case "string": - { - try - { - propertyInfo.SetValue(config, value); - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - - return; - } - case "bool": - { - // 空字符串 - - value = value.ToLower(); - - if (IsNullOrEmpty(value)) - { - propertyInfo.SetValue(config, false); - } - else if (bool.TryParse(value, out bool b)) - { - propertyInfo.SetValue(config, b); - } - else if (int.TryParse(value, out int v)) - { - propertyInfo.SetValue(config, v != 0); - } - else - { - propertyInfo.SetValue(config, false); - } - - return; - } - case "ulong": - { - propertyInfo.SetValue(config, Convert.ToUInt64(value)); - return; - } - case "long": - { - propertyInfo.SetValue(config, Convert.ToInt64(value)); - return; - } - case "double": - { - propertyInfo.SetValue(config, Convert.ToDouble(value)); - return; - } - case "float": - { - propertyInfo.SetValue(config, Convert.ToSingle(value)); - return; - } - case "int32[]": - case "int[]": - { - if (value != "0") - { - propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToInt32(d)).ToArray()); - } - - return; - } - case "uint[]": - { - if (value != "0") - { - propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToUInt32(d)).ToArray()); - } - - return; - } - case "long[]": - { - if (value != "0") - { - propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToInt64(d)).ToArray()); - } - - return; - } - case "double[]": - { - if (value != "0") - { - propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToDouble(d)).ToArray()); - } - - return; - } - case "string[]": - { - if (value == "0") - { - return; - } - - var list = value.Split(",").ToArray(); - - for (var i = 0; i < list.Length; i++) - { - list[i] = list[i].Replace("\"", ""); - } - - propertyInfo.SetValue(config, value.Split(",").ToArray()); - - return; - } - case "float[]": - { - if (value != "0") - { - propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToSingle(d)).ToArray()); - } - - return; - } - case "IntDictionaryConfig": - { - if (value.Trim() == "" || value.Trim() == "{}") - { - propertyInfo.SetValue(config, null); - return; - } - - var attr = new IntDictionaryConfig { Dic = JsonConvert.DeserializeObject>(value) }; - - propertyInfo.SetValue(config, attr); - - return; - } - case "StringDictionaryConfig": - { - if (value.Trim() == "" || value.Trim() == "{}") - { - propertyInfo.SetValue(config, null); - return; - } - - var attr = new StringDictionaryConfig - { Dic = JsonConvert.DeserializeObject>(value) }; - - propertyInfo.SetValue(config, attr); - - return; - } - default: - throw new NotSupportedException($"不支持此类型: {type}"); - } - } - private bool IsArray(string type, out string t) { t = null; diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelTable.cs b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelTable.cs index 20f0558..dd5a525 100644 --- a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelTable.cs +++ b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelTable.cs @@ -1,3 +1,5 @@ +using OfficeOpenXml; + namespace NBConfigBuilder; /// @@ -9,20 +11,29 @@ public sealed class ExcelTable /// 表格的名称。 /// public readonly string Name; + /// /// 客户端列信息,使用排序字典存储列名和列索引列表。 /// public readonly SortedDictionary> ClientColInfos = new(); + /// /// 服务器端列信息,使用排序字典存储列名和列索引列表。 /// public readonly SortedDictionary> ServerColInfos = new(); + + /// + /// 表数据 + /// + public readonly ExcelWorksheet Sheet; + /// /// 构造函数,初始化Excel表格对象并设置表格名称。 /// - /// 表格名称。 - public ExcelTable(string name) + /// 表格。 + public ExcelTable(ExcelWorksheet sheet) { - Name = name; + Name = sheet.Name; + Sheet = sheet; } } \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelTemplate.cs b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelTemplate.cs index c3f67ff..d12466e 100644 --- a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelTemplate.cs +++ b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelTemplate.cs @@ -10,8 +10,13 @@ public static class ExcelTemplate using System.Reflection; using System.Collections.Generic; using System.Collections.Concurrent; + #if FANTASY_NET using Fantasy.ConfigTable; using Fantasy.Serialize; + #else + using NBC; + using NBC.Serialize; + #endif // ReSharper disable CollectionNeverUpdated.Global // ReSharper disable UnusedAutoPropertyAccessor.Global #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelWorksheets.cs b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelWorksheets.cs index cf4277a..1c23c40 100644 --- a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelWorksheets.cs +++ b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelWorksheets.cs @@ -1,22 +1,22 @@ -using OfficeOpenXml; - -namespace NBConfigBuilder; - -public sealed class ExcelWorksheets(ExcelExporter excelExporter) -{ - public bool TryGetValue(string worksheetName, out ExcelWorksheet excelWorksheet) - { - if (excelExporter.Worksheets.TryGetValue(worksheetName, out excelWorksheet)) - { - return true; - } - - var computeHash64 = HashCodeHelper.ComputeHash64(worksheetName); - if (!excelExporter.VersionInfo.WorksheetNames.Contains(computeHash64)) - { - Log.Info($"{worksheetName} is not exist!"); - } - - return false; - } -} \ No newline at end of file +// using OfficeOpenXml; +// +// namespace NBConfigBuilder; +// +// public sealed class ExcelWorksheets(ExcelExporter excelExporter) +// { +// public bool TryGetValue(string worksheetName, out ExcelWorksheet excelWorksheet) +// { +// if (excelExporter.Worksheets.TryGetValue(worksheetName, out excelWorksheet)) +// { +// return true; +// } +// +// var computeHash64 = HashCodeHelper.ComputeHash64(worksheetName); +// if (!excelExporter.VersionInfo.WorksheetNames.Contains(computeHash64)) +// { +// Log.Info($"{worksheetName} is not exist!"); +// } +// +// return false; +// } +// } \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExportInfo.cs b/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExportInfo.cs deleted file mode 100644 index d9d7b91..0000000 --- a/Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExportInfo.cs +++ /dev/null @@ -1,17 +0,0 @@ -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. -namespace NBConfigBuilder; - -/// -/// 导出信息类,用于存储导出操作的名称和文件信息。 -/// -public class ExportInfo -{ - /// - /// 导出操作的名称。 - /// - public string Name; - /// - /// 导出操作生成的文件信息。 - /// - public FileInfo FileInfo; -} \ No newline at end of file diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Form1.Designer.cs b/Tools/ConfigBuilder/NBConfigBuilder/Form1.Designer.cs index b1a50ee..43061d6 100644 --- a/Tools/ConfigBuilder/NBConfigBuilder/Form1.Designer.cs +++ b/Tools/ConfigBuilder/NBConfigBuilder/Form1.Designer.cs @@ -100,7 +100,7 @@ checkBoxGenClient.Name = "checkBoxGenClient"; checkBoxGenClient.Size = new Size(87, 21); checkBoxGenClient.TabIndex = 5; - checkBoxGenClient.Text = "生产服务端"; + checkBoxGenClient.Text = "生成客户端"; checkBoxGenClient.UseVisualStyleBackColor = true; // // label2 @@ -137,7 +137,7 @@ checkBoxGenServer.Name = "checkBoxGenServer"; checkBoxGenServer.Size = new Size(87, 21); checkBoxGenServer.TabIndex = 9; - checkBoxGenServer.Text = "生产客户端"; + checkBoxGenServer.Text = "生成服务端"; checkBoxGenServer.UseVisualStyleBackColor = true; // // buttonSelectServerPath diff --git a/Tools/ConfigBuilder/NBConfigBuilder/Form1.cs b/Tools/ConfigBuilder/NBConfigBuilder/Form1.cs index c41e3c9..cf7eacc 100644 --- a/Tools/ConfigBuilder/NBConfigBuilder/Form1.cs +++ b/Tools/ConfigBuilder/NBConfigBuilder/Form1.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using System.Threading.Tasks; namespace NBConfigBuilder { @@ -7,6 +8,9 @@ namespace NBConfigBuilder // 配置文件路径 private readonly string configPath = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath) ?? string.Empty, "config.json"); + + // 保存原始标题 + private string _originalTitle; public Form1() { @@ -14,16 +18,64 @@ namespace NBConfigBuilder // 设置窗口大小不可变 this.FormBorderStyle = FormBorderStyle.FixedSingle; this.MaximizeBox = false; + + // 保存原始标题 + _originalTitle = this.Text; // 加载保存的配置 LoadConfig(); } - private void buttonRun_Click(object sender, EventArgs e) + private async void buttonRun_Click(object sender, EventArgs e) { - // 保存当前配置 - SaveConfig(); - new ExcelExporter(ExportType.AllExcel).Run(); + // 禁用按钮防止重复点击 + buttonRun.Enabled = false; + buttonRun.Text = "执行中..."; + + try + { + // 保存当前配置 + SaveConfig(); + + // 创建导出器并设置进度回调 + var exporter = new ExcelExporter(ExportType.AllExcel); + exporter.SetProgressCallback(UpdateProgress); + + // 运行导出器 + await Task.Run(() => exporter.Run()); + + // 显示成功消息 + MessageBox.Show("配置导出完成!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + // 显示错误消息 + MessageBox.Show($"导出过程中发生错误:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + finally + { + // 恢复按钮状态和标题 + buttonRun.Enabled = true; + buttonRun.Text = "执行"; + this.Text = _originalTitle; + } + } + + /// + /// 更新进度显示 + /// + /// 进度消息 + private void UpdateProgress(string message) + { + // 确保在UI线程上更新界面 + if (InvokeRequired) + { + Invoke(new Action(UpdateProgress), message); + return; + } + + // 更新标题栏显示进度 + this.Text = $"{_originalTitle} - {message}"; } private void buttonSelectExcelPath_Click(object sender, EventArgs e)