//加载Xml文件 public void LoadXml(string filepathname, List <XmlSheet> allSheetList) { XmlDocument doc = new XmlDocument(); doc.Load(filepathname); XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); nsmgr.AddNamespace("default", "urn:schemas-microsoft-com:office:spreadsheet"); var sheets = doc.SelectNodes("//default:Workbook/default:Worksheet", nsmgr); if (sheets.Count == 0) { throw new Exception("No sheet in the xml file:" + Path.GetFileName(filepathname)); } //遍历所有sheet for (int i = 0; i < sheets.Count; i++) { XmlAttribute att = sheets[i].Attributes["ss:Name"]; if (att != null) { var sheetName = att.InnerText; if (sheets.Count == 1)//如果只有1个sheet,那么用文件名作为表名 { sheetName = Path.GetFileNameWithoutExtension(filepathname); } XmlSheet sheet = null; if (sheetName == "Strings") { sheet = new XmlSheet_Strings(sheetName); } else { sheet = new XmlSheet(sheetName); } sheet.Load(sheets[i], nsmgr); allSheetList.Add(sheet); } } }
//生成Bin文件 static void WriteSheet2BinFile(XmlSheet sheet, bool isServer) { try { string binFileName = "./../Output/Bin_" + (isServer ? "S" : "C") + "/" + sheet.mName + ".bytes"; string binTmpFileName = binFileName + ".tmp"; var fs = new FileStream(binTmpFileName, FileMode.Create); var bw = new BinaryWriter(fs); string funcString = "public static int WriteData" + sheet.mName + "_" + (isServer ? "S" : "C") + "(System.IO.BinaryWriter bw){\r\ntry{\r\n"; //写一行数据 Action <string, string, int, int> funcStringWriteLine = (tTypeStr, tValue, r, c) => { if (tTypeStr == "long" || tTypeStr == "ulong" || tTypeStr == "int" || tTypeStr == "uint" || tTypeStr == "short" || tTypeStr == "ushort" || tTypeStr == "byte" || tTypeStr == "float" || tTypeStr == "double") { //数字型 if (tValue == "") { tValue = "0"; } funcString += "bw.Write((" + tTypeStr + ")" + tValue + ");\r\n"; } else if (tTypeStr == "bool") { //布尔布 var lowerValue = tValue.ToLower(); if (lowerValue == "0") { lowerValue = "false"; } else if (lowerValue == "1") { lowerValue = "true"; } else if (lowerValue != "true" && lowerValue != "false") { lowerValue = "false"; } //尔 funcString += "bw.Write((" + tTypeStr + ")" + lowerValue + ");\r\n"; } else if (tTypeStr == "string") { //字符串型 funcString += "bw.Write((" + tTypeStr + ")\"" + tValue + "\");\r\n"; } else if (tTypeStr == "string reference") { //字符串引用,转换成ushort型的id if (tValue != "") { if (XmlSheet_Strings.sRef2IDMap.ContainsKey(tValue) == false) { throw new Exception("Can't find string ref '" + tValue + "'. Sheet=" + sheet.mName); } funcString += "bw.Write((ushort)" + XmlSheet_Strings.sRef2IDMap[tValue] + ");\r\n"; } else { funcString += "bw.Write((ushort)" + "0" + ");\r\n"; } } else if (tTypeStr.Contains("enum")) { //枚举 var enumArray = tTypeStr.Split(":".ToCharArray()); if (enumArray.Length < 2) { throw new Exception("header enum type error at col " + c); } string enumTypeStr = enumArray[1]; funcString += "bw.Write((ushort)" + enumTypeStr + "." + tValue + ");\r\n"; } else { //未识别类型 throw new Exception("Unrecognized type of " + tTypeStr + " at row:" + r + " col:" + c); } }; //读表格中所有的行 for (int r = 0; r < sheet.mValues.Count; r++) { //数据第0行就是真实数据。表头3行已去掉 //列 for (int c = 0; c < sheet.mComments.Count; c++) { if (isServer) {//服务器 if (sheet.mRangeType[c] == XmlSheet.ERangeType.Client || sheet.mRangeType[c] == XmlSheet.ERangeType.None) { continue; } } else {//客户端 if (sheet.mRangeType[c] == XmlSheet.ERangeType.Server || sheet.mRangeType[c] == XmlSheet.ERangeType.None) { continue; } } var curTypeStr = sheet.mTypes[c]; if (curTypeStr.Contains("[")) {//数组 int startIdx_Bracket = curTypeStr.IndexOf('['); int endIdx_Bracket = curTypeStr.IndexOf(']'); var arrayTypeStr = curTypeStr.Substring(0, startIdx_Bracket); int arrayCount = 0; if (false == Int32.TryParse(curTypeStr.Substring(startIdx_Bracket + 1, endIdx_Bracket - startIdx_Bracket - 1), out arrayCount)) { throw new Exception("Array Capacity is missing at row:" + r + " col:" + c); } string[] arrayValue = sheet.mValues[r][c].Split("|".ToCharArray()); if (arrayValue.Length != arrayCount) { throw new Exception("Data array count is not valid at row:" + r + " col:" + c); } //数量 funcStringWriteLine("ushort", arrayCount.ToString(), r, c); for (int i = 0; i < arrayCount; i++) { funcStringWriteLine(arrayTypeStr, arrayValue[i], r, c);//数据 } } else if (curTypeStr.Contains("List")) {//集合 int startIdx_Bracket = curTypeStr.IndexOf('<'); int endIdx_Bracket = curTypeStr.IndexOf('>'); var arrayTypeStr = curTypeStr.Substring(startIdx_Bracket + 1, endIdx_Bracket - startIdx_Bracket - 1); string[] arrayValue = sheet.mValues[r][c].Split("|".ToCharArray()); funcStringWriteLine("ushort", arrayValue.Length.ToString(), r, c); for (int i = 0; i < arrayValue.Length; i++) { funcStringWriteLine(arrayTypeStr, arrayValue[i], r, c);//数据 } } else {//非数组集合 funcStringWriteLine(curTypeStr, sheet.mValues[r][c], r, c); } } //for col } //for row funcString += "return 0;\r\n}catch(Exception e){Console.WriteLine(e.ToString());return 1; \r\n}\r\n}"; //结束 Console.WriteLine("--" + funcString); RunFunction <int>(funcString, 0, (object)bw); bw.Close(); //加密 FileDes.EncryptFile(binTmpFileName, binFileName, false); } catch (Exception e) { Console.WriteLine(e.ToString()); } }
//生成CS文件 static void WriteSheet2CSFile(XmlSheet sheet, bool isServer) { var csFileName = "./../Output/Code_" + (isServer?"S":"C") + "/Data/" + sheet.mName + "Data.cs"; var finalContent = mDataFileTemplate;//保存最终结果的变量 //类名 var className = sheet.mName + "Data"; finalContent = finalContent.Replace("{$ClassName}", className); //成员和读数据 string memberVars = ""; //成员变量 string readDataCode = ""; //读数据的代码 //读表格中所有的列 for (int i = 0; i < sheet.mComments.Count; i++) { if (isServer) {//服务器 if (sheet.mRangeType[i] == XmlSheet.ERangeType.Client || sheet.mRangeType[i] == XmlSheet.ERangeType.None) { continue; } } else {//客户端 if (sheet.mRangeType[i] == XmlSheet.ERangeType.Server || sheet.mRangeType[i] == XmlSheet.ERangeType.None) { continue; } } var curTypeStr = sheet.mTypes[i]; if (curTypeStr == "string reference")//字符串引用,转换成ushort型的id { curTypeStr = "ushort"; } if (curTypeStr == "long" || curTypeStr == "ulong" || curTypeStr == "int" || curTypeStr == "uint" || curTypeStr == "short" || curTypeStr == "ushort" || curTypeStr == "byte" || curTypeStr == "float" || curTypeStr == "double") { //数字型 if (i == 0) { //ID列,特殊处理 sheet.mVarNames[i] = "ID"; } else { memberVars += "public " + curTypeStr + " " + sheet.mVarNames[i] + " = 0;\t//" + sheet.mComments[i]; } readDataCode += sheet.mVarNames[i] + " = br." + mType2ReadFunc[curTypeStr] + ";\t//" + sheet.mComments[i]; } else if (curTypeStr == "string") {//字符串 memberVars += "public " + sheet.mTypes[i] + " " + sheet.mVarNames[i] + " = \"\";\t//" + sheet.mComments[i]; readDataCode += sheet.mVarNames[i] + " = br.ReadString()" + ";\t//" + sheet.mComments[i];; } else if (curTypeStr == "bool") {//布尔 memberVars += "public " + sheet.mTypes[i] + " " + sheet.mVarNames[i] + " = false;\t//" + sheet.mComments[i]; readDataCode += sheet.mVarNames[i] + " = br.ReadBoolean()" + ";\t//" + sheet.mComments[i];; } else if (curTypeStr.Contains("enum")) { //枚举 var enumArray = sheet.mTypes[i].Split(":".ToCharArray()); if (enumArray.Length < 2) { throw new Exception("header enum type error at col " + i); } string enumTypeStr = enumArray[1]; memberVars += "public " + enumTypeStr + " " + sheet.mVarNames[i] + ";\t//" + sheet.mComments[i]; readDataCode += sheet.mVarNames[i] + " = (" + enumTypeStr + ")br.ReadUInt16()" + ";\t//" + sheet.mComments[i]; } else if (curTypeStr.Contains("[")) {//数组 int startIdx_Bracket = curTypeStr.IndexOf('['); int endIdx_Bracket = curTypeStr.IndexOf(']'); var arrayTypeStr = curTypeStr.Substring(0, startIdx_Bracket); var arrayCount = 0; if (false == Int32.TryParse(curTypeStr.Substring(startIdx_Bracket + 1, endIdx_Bracket - startIdx_Bracket - 1), out arrayCount)) { throw new Exception("Array Capacity is missing at col " + i); } memberVars += "public " + arrayTypeStr + "[] " + sheet.mVarNames[i] + " = new " + arrayTypeStr + "[" + arrayCount + "];\t//" + sheet.mComments[i]; readDataCode += "ushort cnt" + arrayCount + "_" + i + " = br.ReadUInt16();\r\n\t\t\t"; readDataCode += "for(ushort i = 0; i < cnt" + arrayCount + "_" + i + "; i++)\r\n\t\t\t\t" + sheet.mVarNames[i] + "[i] = br." + mType2ReadFunc[arrayTypeStr] + ";\t//" + sheet.mComments[i]; } else if (curTypeStr.Contains("List")) {//集合 int startIdx_Bracket = curTypeStr.IndexOf('<'); int endIdx_Bracket = curTypeStr.IndexOf('>'); var arrayTypeStr = curTypeStr.Substring(startIdx_Bracket + 1, endIdx_Bracket - startIdx_Bracket - 1); memberVars += "public List<" + arrayTypeStr + "> " + sheet.mVarNames[i] + " = new List<" + arrayTypeStr + ">();\t//" + sheet.mComments[i]; readDataCode += "ushort listCount_" + i + " = br.ReadUInt16();\r\n\t\t\t"; readDataCode += "for(ushort i = 0; i < listCount_" + i + "; i++)\r\n\t\t\t\t" + sheet.mVarNames[i] + ".Add(br." + mType2ReadFunc[arrayTypeStr] + ");\t//" + sheet.mComments[i]; } else {//未识别类型 throw new Exception("Unrecognized type at col " + i); } //换行 memberVars += "\r\n\t\t"; readDataCode += "\r\n\t\t\t"; }//for //替换模板文件中的内容 finalContent = finalContent.Replace("{$MemberVars}", memberVars); finalContent = finalContent.Replace("{$ReadDataCode}", readDataCode); //保存到文件 var fs = new FileStream(csFileName, FileMode.Create); var sWriter = new StreamWriter(fs); sWriter.Write(finalContent); sWriter.Close(); }