/// <summary> /// 解析excel表 /// </summary> /// <param name="filePath"></param> /// <returns></returns> public static ExcelData ParseExcel(string filePath) { DataSet ds = LoadDataFromExcel(filePath); if (ds == null) { return(null); } ExcelData data = new ExcelData(); data.fullFileName = filePath; try { DataTable table = ds.Tables[0]; DataColumn[] columns = new DataColumn[table.Columns.Count]; table.Columns.CopyTo(columns, 0); foreach (var v in columns) // columns是第一行数据 { data.names.Add(v.ToString().Trim().Replace(' ', '_')); // 去掉收尾空字符,将中间空格改为下划线 } int row = 0; foreach (DataRow dr in table.Rows) { for (int c = 0; c < columns.Length; ++c) { object obj = dr[columns[c]]; if (row == 0) // 类型,实际是第二行数据 { ParseType(data, obj, c); continue; } if (row == 1) // 说明,用于代码注释 { data.descriptions.Add(obj.ToString()); continue; } int valueIndex = row - 2; // row从2开始 if (data.values.Count < row - 1) { data.values.Add(new List <string>()); } data.values[valueIndex].Add(obj.ToString()); } ++row; } } catch (Exception ex) { MessageBox.Show(data.fileName + ":" + ex.Message, "数据错误"); return(null); } return(data); }
/// <summary> /// 生成代码 /// </summary> /// <param name="excelData"></param> public static void GenerateCodeData(ExcelData excelData, CodeType codeTypes) { List <IGenerateCode> list = new List <IGenerateCode>(); if ((codeTypes & CodeType.U3D_CS) != CodeType.NULL) { list.Add(new U3dCsGenerateCode()); } foreach (var v in list) { v.GenerateCodeData(excelData); } }
/// <summary> /// 一键Build /// </summary> /// <param name="filePath"></param> public static void OneKeyBuild(string[] filePaths, CodeType codeTypes) { try { foreach (var v in filePaths) { ExcelData excelData = ParseExcel(v); if (excelData != null) { GenerateCodeData(excelData, codeTypes); GenerateBinaryData(excelData); } } MessageBox.Show("生成完成!", "Build"); } catch (Exception ex) { MessageBox.Show(ex.Message, "Build"); } }
public void GenerateCodeData(ExcelData excelData) { try { StringBuilder codeBuilder = new StringBuilder(); List <int> mainKeyIndexList = new List <int>(excelData.mainKeyIndexs); // 主关键字列表 int[] ignoreFieldIndexArray = excelData.ignoreFieldIndexs.ToArray(); // 忽略字段列表 mainKeyIndexList.RemoveAll((match) => { return(excelData.ignoreFieldIndexs.Contains(match)); }); if (mainKeyIndexList.Count == 0) { throw new Exception("没有有效的关键字段"); } // 生成文件头 string date = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString(); StringBuilder mainKeyBuilder = new StringBuilder(); // 文件头关键字段说明 foreach (var v in mainKeyIndexList) { mainKeyBuilder.Append(excelData.names[v]).Append(" "); } StringBuilder ignoreKeyBuilder = new StringBuilder(); // 文件头忽略字段说明 foreach (var v in excelData.ignoreFieldIndexs) { ignoreKeyBuilder.Append(excelData.names[v]).Append(" "); } string headText = FormatCode(codeHeadTemplate, date, excelData.fileNameWithExtension, mainKeyBuilder, ignoreKeyBuilder); codeBuilder.Append(headText); StringBuilder classCodeBuilder = new StringBuilder(); // 类代码部分,不含文件头说明和命名空间 // 生成主键,key超过1时生成数据结构 if (mainKeyIndexList.Count > 1) { TableDataType[] mainKeyTypes = new TableDataType[mainKeyIndexList.Count]; string[] mainKeyAttributeNames = new string[mainKeyIndexList.Count]; string[] mainKeyComments = new string[mainKeyIndexList.Count]; for (int i = 0; i < mainKeyIndexList.Count; ++i) { int index = mainKeyIndexList[i]; mainKeyTypes[i] = excelData.types[index]; mainKeyAttributeNames[i] = excelData.names[index]; mainKeyComments[i] = excelData.descriptions[index]; } string mainKeyAttributeCode = GenerateAttributeCode(mainKeyTypes, mainKeyAttributeNames, mainKeyComments, new int[0]); classCodeBuilder.Append(FormatCode( codeStructTemplate, GetKeyStructName(excelData.fileName), mainKeyAttributeCode )); } // 生成数据结构 StringBuilder dataCodeBuilder = new StringBuilder(); // 数据代码 string dataAttributeCode = GenerateAttributeCode(excelData.types.ToArray(), excelData.names.ToArray(), excelData.descriptions.ToArray(), ignoreFieldIndexArray); dataCodeBuilder.Append(dataAttributeCode).Append("\r\n"); StringBuilder newKeyBuilder = new StringBuilder(); // 实例化key string keyTypeString = ""; if (mainKeyIndexList.Count > 1) // 多个参数时 { newKeyBuilder.Append("\t\tvar key = new ").Append(GetKeyStructName(excelData.fileName)).Append("();\r\n"); for (int i = 0; i < mainKeyIndexList.Count; ++i) { int index = mainKeyIndexList[i]; string paramName = excelData.names[index]; newKeyBuilder.Append("\t\tkey.").Append(paramName).Append(" = ").Append(paramName).Append(";"); if (i != mainKeyIndexList.Count - 1) { newKeyBuilder.Append("\r\n"); } } keyTypeString = GetKeyStructName(excelData.fileName); } else { int index = mainKeyIndexList[0]; newKeyBuilder.Append("\t\tvar key = ").Append(excelData.names[index]).Append(";"); keyTypeString = GenerateTypeByTableDataType(excelData.types[index], excelData.names[index]); } dataCodeBuilder.Append(FormatCode(codeGetKeyTemplate, keyTypeString, newKeyBuilder)); classCodeBuilder.Append(FormatCode( codeStructTemplate, GetDataStructName(excelData.fileName), dataCodeBuilder )); // 生成枚举 List <int> enumIndexs = new List <int>(); for (int i = 0; i < excelData.types.Count; ++i) { if (excelData.types[i] == TableDataType.ENUM && excelData.enumTypeIndexs.Contains(i)) // 判断是枚举类型且标记"#" { enumIndexs.Add(i); } } if (enumIndexs.Count > 0) { string[] attributeNames = new string[enumIndexs.Count]; string[] typeStrings = new string[enumIndexs.Count]; for (int i = 0; i < enumIndexs.Count; ++i) { int index = enumIndexs[i]; attributeNames[i] = excelData.names[index]; typeStrings[i] = excelData.typeStrings[index]; } string enumCode = GenerateEnemCode(attributeNames, typeStrings); classCodeBuilder.Append(enumCode); } // 生成数据管理器 string[] managerCodeUnits = new string[11]; managerCodeUnits[0] = excelData.fileName; string keyType = ""; if (mainKeyIndexList.Count > 1) { keyType = GetKeyStructName(excelData.fileName); } else { int index = mainKeyIndexList[0]; keyType = GenerateTypeByTableDataType(excelData.types[index], excelData.names[index]); } managerCodeUnits[1] = managerCodeUnits[3] = managerCodeUnits[5] = keyType; managerCodeUnits[2] = managerCodeUnits[4] = managerCodeUnits[6] = managerCodeUnits[7] = managerCodeUnits[8] = GetDataStructName(excelData.fileName); StringBuilder addItemParamBuilder = new StringBuilder(); for (int i = 0; i < mainKeyIndexList.Count; ++i) { int index = mainKeyIndexList[i]; string paramType = GenerateTypeByTableDataType(excelData.types[index], excelData.names[i]); addItemParamBuilder.Append(paramType).Append(" ").Append(excelData.names[i]); if (i != mainKeyIndexList.Count - 1) { addItemParamBuilder.Append(", "); } } managerCodeUnits[9] = addItemParamBuilder.ToString(); managerCodeUnits[10] = newKeyBuilder.ToString(); // 与GetKey函数相同 classCodeBuilder.Append(FormatCode(codeManagerTemplate, managerCodeUnits)); // 将类代码、命名空间添加到代码 string namespaceClassCode = FormatCode(namespaceTemplate, classCodeBuilder); codeBuilder.Append(namespaceClassCode); // 保存代码文件 string codeFilePath = excelData.path + "/" + excelData.fileName + ".cs"; using (StreamWriter sw = new StreamWriter(codeFilePath, false)) { sw.Write(codeBuilder); } } catch (Exception ex) { throw new Exception(excelData.fileName + ":" + ex.Message, ex); } }
/// <summary> /// 解析指定类型 /// </summary> /// <param name="data"></param> /// <param name="obj"></param> /// <param name="colmunsIndex"></param> private static void ParseType(ExcelData data, object obj, int colmunsIndex) { string assignTypeString = obj.ToString().Trim(); data.typeStrings.Add(assignTypeString); string assignTypeSymbol = assignTypeString.Split(new char[] { '\n', '\r' }, System.StringSplitOptions.RemoveEmptyEntries)[0]; // 提取标记符号 List <char> assignFlagSymbolList = new List <char>(); // 指定标记符号列表 for (int i = 0; i < assignTypeSymbol.Length; ++i) { char c = assignTypeSymbol[i]; bool b = false; switch (c) { case '*': // 主键 data.mainKeyIndexs.Add(colmunsIndex); break; case '#': // 生成枚举定义代码 data.enumTypeIndexs.Add(colmunsIndex); break; case '-': // 忽略,不生成 data.ignoreFieldIndexs.Add(colmunsIndex); break; default: b = true; assignTypeSymbol = assignTypeSymbol.Substring(i); break; } if (b) { break; } } switch (assignTypeSymbol) { case "INT": data.types.Add(TableDataType.INT); break; case "FLOAT": data.types.Add(TableDataType.FLOAT); break; case "STRING": data.types.Add(TableDataType.STRING); break; case "ENUM": data.types.Add(TableDataType.ENUM); break; case "LONG": data.types.Add(TableDataType.LONG); break; case "DOUBLE": data.types.Add(TableDataType.DOUBLE); break; // TODO:根据需求扩展类型 default: Console.WriteLine("指定类型{0}不存在", assignTypeSymbol); break; } }
/// <summary> /// 生成二进制数据 /// </summary> /// <param name="excelData"></param> public static void GenerateBinaryData(ExcelData excelData) { string bytesFileName = excelData.path + "/" + excelData.fileName + ".bytes"; using (BinaryWriter writer = new BinaryWriter(File.Open(bytesFileName, FileMode.Create))) { writer.Write(dataVersion); // 版本号 writer.Write(excelData.values.Count); for (int i = 0; i < excelData.types.Count; ++i) { if (excelData.ignoreFieldIndexs.Contains(i)) { continue; } writer.Write((Byte)excelData.types[i]); } foreach (var lineData in excelData.values) { for (int i = 0; i < lineData.Count; ++i) { if (excelData.ignoreFieldIndexs.Contains(i)) { continue; } switch (excelData.types[i]) { case TableDataType.INT: int intData = 0; int.TryParse(lineData[i], out intData); writer.Write(intData); break; case TableDataType.FLOAT: float floatData = 0f; float.TryParse(lineData[i], out floatData); writer.Write(floatData); break; case TableDataType.STRING: writer.Write(lineData[i]); break; case TableDataType.ENUM: int enumData = 0; int.TryParse(lineData[i], out enumData); writer.Write(enumData); break; case TableDataType.LONG: long longData = 0L; long.TryParse(lineData[i], out longData); writer.Write(longData); break; case TableDataType.DOUBLE: double doubleData = 0d; double.TryParse(lineData[i], out doubleData); writer.Write(doubleData); break; // TODO:根据需求扩展类型 default: break; } } } } }