using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.Data; using Excel; using System.IO; using LitJson; using System.Text; using System.Text.RegularExpressions; using System; using Unity.VisualScripting; namespace ZXKFrameworkEditor { public class ExcelToJson : EditorWindow { private string JsonPath; private string JsonPathStreamingAssets; string CSharpPath; string JsonName; List dataDoc = new List(); List dataType = new List(); List dataName = new List(); List ExcelDateList = new List(); List allDataClassName = new List();//所有类名 StringBuilder allFindUnc = new StringBuilder(); string nameSpace; string folderName; private int selectedIndex = 0; private bool onlytime = true; [UnityEditor.MenuItem("ZXKFramework/ExcelToJson")] static void ExceltoJson() { ExcelToJson toJson = (ExcelToJson)EditorWindow.GetWindow(typeof(ExcelToJson), true, "ExcelToJson"); toJson.Show(); } private void OnGUI() { if (onlytime) { selectedIndex = Array.IndexOf(getAllSceneName(), UnityEngine.SceneManagement.SceneManager.GetActiveScene().name); onlytime = false; } selectedIndex = EditorGUILayout.Popup("场景:", selectedIndex, getAllSceneName()); if (GUILayout.Button("生成Json")) { if(getAllSceneName()[selectedIndex] != "Main") { List data = JsonMapper.ToObject>(Resources.Load("Main/ExcelData/ExcelToJson/MainData").text); nameSpace = null; folderName = null; for (int i = 0; i < data.Count; i++) { if (getAllSceneName()[selectedIndex] == data[i]["scene"].ToString()) { nameSpace = data[i]["nameSpace"].ToString(); Debug.LogError(nameSpace); folderName = data[i]["folder"].ToString(); } } if (string.IsNullOrEmpty(nameSpace)) { Debug.LogError("命名空间不能为空"); return; } if (string.IsNullOrEmpty(folderName)) { Debug.LogError("文件夹名不能为空"); return; } } else { nameSpace = "DongWuYiXue.Main"; folderName = "Main"; Debug.LogError(nameSpace); } GetAllExcelPath(); } } #region Excel文件处理 public void GetAllExcelPath() { EditorTools.CreateDirectory(Application.dataPath + "/Resources/" + folderName + "/ExcelData/Excel/"); EditorTools.CreateDirectory(Application.dataPath + "/_Scripts/Application/" + folderName + "/ExcelData/CSharpPath/"); EditorTools.CreateDirectory(Application.dataPath + "/Resources/" + folderName + "/ExcelData/ExcelToJson/"); EditorTools.CreateDirectory(Application.streamingAssetsPath + "/" + folderName + "/ExcelData/ExcelToJson/"); EditorTools.CreateDirectory(Application.streamingAssetsPath + "/" + folderName + "/AssetBundles/Android/"); EditorTools.CreateDirectory(Application.streamingAssetsPath + "/" + folderName + "/AssetBundles/StandaloneWindows/"); EditorTools.CreateDirectory(Application.streamingAssetsPath + "/" + folderName + "/AssetBundles/WebGL/"); EditorTools.CreateDirectory(Application.streamingAssetsPath + "/" + folderName + "/Sounds/"); EditorTools.CreateDirectory(Application.streamingAssetsPath + "/" + folderName + "/Textures/"); string loPath = Application.dataPath + "/Resources/" + folderName + "/ExcelData/Excel/"; DirectoryInfo dir = new DirectoryInfo(loPath); FileInfo[] fil = dir.GetFiles(); allDataClassName.Clear(); foreach (FileInfo f in fil) { if (f.FullName.EndsWith(".meta")) { continue; } //Debug.Log(f.FullName); ReadExcel(f.FullName.Replace("\\", "/"), Path.GetFileNameWithoutExtension(f.Name)); } CreatCSharpExcelData(); AssetDatabase.Refresh(); Debug.Log(folderName + " Json生成成功"); } public void GetAllExcelPath(string folderName,string nameSpace) { this.folderName = folderName; this.nameSpace = nameSpace; EditorTools.CreateDirectory(Application.dataPath + "/Resources/" + folderName + "/ExcelData/Excel/"); EditorTools.CreateDirectory(Application.dataPath + "/_Scripts/Application/" + folderName + "/ExcelData/CSharpPath/"); EditorTools.CreateDirectory(Application.dataPath + "/Resources/" + folderName + "/ExcelData/ExcelToJson/"); EditorTools.CreateDirectory(Application.streamingAssetsPath + "/" + folderName + "/ExcelData/ExcelToJson/"); string loPath = Application.dataPath + "/Resources/" + folderName + "/ExcelData/Excel/"; DirectoryInfo dir = new DirectoryInfo(loPath); FileInfo[] fil = dir.GetFiles(); allDataClassName.Clear(); foreach (FileInfo f in fil) { if (f.FullName.EndsWith(".meta")) { continue; } //Debug.Log(f.FullName); ReadExcel(f.FullName.Replace("\\", "/"), Path.GetFileNameWithoutExtension(f.Name)); } CreatCSharpExcelData(); AssetDatabase.Refresh(); Debug.Log(folderName + " Json生成成功"); } /// /// 读取Excel /// /// excel路径 /// 列 /// 行 void ReadExcel(string path, string fileName) { FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read); IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream); DataSet data = excelReader.AsDataSet(); dataDoc.Clear(); dataName.Clear(); dataType.Clear(); ExcelDateList.Clear(); //读取Excel的所有页签 for (int i = 0; i < data.Tables.Count; i++) { //i代表每一页,一般只有一页,下面为每一页的每一行 每一列 DataRowCollection dataRow = data.Tables[i].Rows; // 每行 DataColumnCollection dataColumn = data.Tables[i].Columns; // 每列 string tableName = fileName; JsonName = fileName + ".json"; JsonPath = Application.dataPath + "/Resources/" + folderName + "/ExcelData/ExcelToJson/" + JsonName; JsonPathStreamingAssets = Application.streamingAssetsPath + "/" + folderName + "/ExcelData/ExcelToJson/" + JsonName; //循环,第一行 for (int rowNum = 0; rowNum < data.Tables[i].Rows.Count; rowNum++) { //第一行的每一列 string[] table = new string[data.Tables[i].Columns.Count]; for (int columnNum = 0; columnNum < data.Tables[i].Columns.Count; columnNum++) { if (rowNum == 0) { //第一行:解释说明 } else if (rowNum == 1) { dataDoc.Add(data.Tables[i].Rows[rowNum][columnNum].ToString()); } else if (rowNum == 2) { dataType.Add(data.Tables[i].Rows[rowNum][columnNum].ToString()); } else if (rowNum == 3) { dataName.Add(data.Tables[i].Rows[rowNum][columnNum].ToString()); } else { table[columnNum] = data.Tables[i].Rows[rowNum][columnNum].ToString(); } } if (rowNum > 3) { //将一行数据存入list ExcelDateList.Add(table); } } CreatJsonFile(); CreatCSharpString(tableName); allDataClassName.Add(tableName); for (int j = 0; j < dataName.Count; j++) { string fangFaBase = @" public # Get#*(% *) { for (int i = 0; i < all#.Count; i++) { if (all#[i].* == *) { return all#[i]; } } return null; } public List<%> GetList#*() { List<%> res = new List<%>(); for (int i = 0; i < all#.Count; i++) { if (!res.Contains(all#[i].*)) { res.Add(all#[i].*); } } return res; } "; fangFaBase = fangFaBase.Replace("#", tableName); fangFaBase = fangFaBase.Replace("*", dataName[j]); fangFaBase = fangFaBase.Replace("%", dataType[j]); allFindUnc.AppendLine(fangFaBase); List res = new List(); } } } #endregion #region Excel转json void CreatJsonFile() { if (File.Exists(JsonPath)) { File.Delete(JsonPath); } if (File.Exists(JsonPathStreamingAssets)) { File.Delete(JsonPathStreamingAssets); } JsonData jsonDatas = new JsonData(); jsonDatas.SetJsonType(JsonType.Array); for (int i = 0; i < ExcelDateList.Count; i++) { JsonData jsonData = new JsonData(); for (int j = 0; j < dataName.Count; j++) { string tempData = dataType[j].Trim(); string loData = ExcelDateList[i][j].Trim(); //Debug.Log("类型 " + tempData + " " + loData); try { switch (tempData) { case "int": int resInt = 0; if (!string.IsNullOrEmpty(loData)) { resInt = Int32.Parse(loData); } jsonData[dataName[j]] = resInt; break; case "float": float resFloat = 0; if (!string.IsNullOrEmpty(loData)) { resFloat = float.Parse(loData); } jsonData[dataName[j]] = resFloat; break; case "double": double resDouble = 0; if (!string.IsNullOrEmpty(loData)) { resDouble = double.Parse(loData); } jsonData[dataName[j]] = resDouble; break; case "bool": bool resBool = false; if (!string.IsNullOrEmpty(loData)) { resBool = bool.Parse(loData); } jsonData[dataName[j]] = resBool; break; default: jsonData[dataName[j]] = loData; break; } } catch (Exception e) { Debug.LogError(e); return; } } jsonDatas.Add(jsonData); } string json = jsonDatas.ToJson(); //防止中文乱码 Regex reg = new Regex(@"(?i)\\[uU]([0-9a-f]{4})"); StreamWriter writer = new StreamWriter(JsonPath, false, Encoding.GetEncoding("UTF-8")); writer.WriteLine ( reg.Replace(json, delegate (Match m){return ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString();}).Replace("\\n","") ); writer.Flush(); writer.Close(); StreamWriter writerSA = new StreamWriter(JsonPathStreamingAssets, false, Encoding.GetEncoding("UTF-8")); writerSA.WriteLine ( reg.Replace(json, delegate (Match m) { return ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString(); }).Replace("\\n", "") ); writerSA.Flush(); writerSA.Close(); } #endregion StringBuilder str = new StringBuilder(); void CreatCSharpString(string name) { string fangFaBase = @" namespace ZXKFramework { public class $ { * } } "; if (!string.IsNullOrEmpty(nameSpace)) { fangFaBase = fangFaBase.Replace("ZXKFramework", nameSpace); } fangFaBase = fangFaBase.Replace("$", name); str.Length = 0; for (int i = 0; i < dataName.Count; i++) { str.Append("//" + dataDoc[i]); str.Append("\n\r"); str.Append("public " + dataType[i] + " " + dataName[i] + ";"); str.Append("\n\r"); } fangFaBase = fangFaBase.Replace("*", str.ToString()); string loPath = Application.dataPath + "/_Scripts/Application/" + folderName + "/ExcelData/CSharpPath/" + name + ".cs"; if (File.Exists(loPath)) File.Delete(loPath); File.WriteAllText(loPath, fangFaBase, Encoding.UTF8); } Type GetTypeForExcel(string Type) { if (Type == "int") return typeof(Int32); if (Type == "float") return typeof(Single); //float关键字是System.Single的别名 if (Type == "double") return typeof(Double); if (Type == "bool") return typeof(Boolean); return typeof(String); } public static string classPath = ""; private static string classTemp = @" using System.Collections; using System.Collections.Generic; namespace ZXKFramework { public class ExcelData { //@ShuXing public IEnumerator Init(string path) { //@FuZhi } //@FangFa } } "; public void CreatCSharpExcelData() { StringBuilder sx = new StringBuilder(); StringBuilder fz = new StringBuilder(); StringBuilder ff = new StringBuilder(); for (int i = 0; i < allDataClassName.Count; i++) { string dataName = allDataClassName[i]; sx.AppendLine($"public List<{dataName}> all{dataName} = null;"); //fz.AppendLine($"ExcelDataTools.GetDataList<{dataName}>(path,value=>all{dataName} = value);"); fz.AppendLine($"yield return ExcelDataTools.GetDataList<{dataName}>(path,value=>all{dataName} = value);"); string fangFaBase = @" public # Get#(int id) { for (int i = 0; i < all#.Count; i++) { if (all#[i].id == id) { return all#[i]; } } return null; }"; fangFaBase = fangFaBase.Replace("#", dataName); ff.AppendLine(fangFaBase); }; ff.AppendLine(allFindUnc.ToString()); allFindUnc.Length = 0; string codeClass = classTemp.Replace("//@ShuXing", sx.ToString()); codeClass = codeClass.Replace("//@FuZhi", fz.ToString()); codeClass = codeClass.Replace("//@FangFa", ff.ToString()); if (!string.IsNullOrEmpty(nameSpace)) { codeClass = codeClass.Replace("ZXKFramework", nameSpace); } classPath = "/_Scripts/Application/" + folderName + "/ExcelData/CSharpPath/" + "ExcelData.cs"; string path = Application.dataPath + classPath; //Debug.Log(path); File.WriteAllText(path, codeClass, Encoding.UTF8); //Debug.Log($"ExcelData生成完毕"); } /// 获取所有场景名字 private string[] getAllSceneName() { List data = JsonMapper.ToObject>(Resources.Load("Main/ExcelData/ExcelToJson/MainData").text); List temp = new(); for (int i = 0; i < data.Count; i++) { if (!string.IsNullOrEmpty(data[i]["scene"].ToString())) { temp.Add(data[i]["scene"].ToString()); } } return temp.ToArray(); } } }