458 lines
18 KiB
C#
Raw Normal View History

2025-09-08 14:51:28 +08:00
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;
2025-09-09 15:06:44 +08:00
using Unity.VisualScripting;
2025-09-08 14:51:28 +08:00
namespace ZXKFrameworkEditor
{
public class ExcelToJson : EditorWindow
{
private string JsonPath;
private string JsonPathStreamingAssets;
string CSharpPath;
string JsonName;
List<string> dataDoc = new List<string>();
List<string> dataType = new List<string>();
List<string> dataName = new List<string>();
List<string[]> ExcelDateList = new List<string[]>();
List<string> allDataClassName = new List<string>();//所有类名
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<JsonData> data = JsonMapper.ToObject<List<JsonData>>(Resources.Load<TextAsset>("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();
2025-09-09 15:06:44 +08:00
Debug.LogError(nameSpace);
2025-09-08 14:51:28 +08:00
folderName = data[i]["folder"].ToString();
}
}
if (string.IsNullOrEmpty(nameSpace))
{
Debug.LogError("命名空间不能为空");
return;
}
if (string.IsNullOrEmpty(folderName))
{
Debug.LogError("文件夹名不能为空");
return;
}
}
else
{
2025-09-09 15:06:44 +08:00
nameSpace = "DongWuYiXue.Main";
2025-09-08 14:51:28 +08:00
folderName = "Main";
2025-09-09 15:06:44 +08:00
Debug.LogError(nameSpace);
2025-09-08 14:51:28 +08:00
}
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生成成功");
}
/// <summary>
/// 读取Excel
/// </summary>
/// <param name="path">excel路径</param>
/// <param name="columnNum">列</param>
/// <param name="rowNum">行</param>
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<string> res = new List<string>();
}
}
}
#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生成完毕");
}
/// <summary>获取所有场景名字</summary>
private string[] getAllSceneName()
{
List<JsonData> data = JsonMapper.ToObject<List<JsonData>>(Resources.Load<TextAsset>("Main/ExcelData/ExcelToJson/MainData").text);
List<string> 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();
}
}
}