2025-05-09 10:20:30 +08:00

416 lines
15 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 System.Reflection;
using System.CodeDom;
using System.CodeDom.Compiler;
namespace ZXKFrameworkEditor
{
public class ExcelToJson : EditorWindow
{
private string JsonPath;
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 = "";
[UnityEditor.MenuItem("ZXKFramework/ExcelToJson")]
static void ExceltoJson()
{
ExcelToJson toJson = (ExcelToJson)EditorWindow.GetWindow(typeof(ExcelToJson), true, "ExcelToJson");
toJson.Show();
}
private void OnGUI()
{
GUILayout.Label("---配表代码自动生成---", EditorStyles.boldLabel);
GUILayout.BeginHorizontal();
GUILayout.Label("命名空间:(选填,用于代码隔离)");
nameSpace = GUILayout.TextField(nameSpace, GUILayout.Width(300));
GUILayout.EndHorizontal();
if (GUILayout.Button("选择需要转换的excel文件"))
{
GetAllExcelPath();
}
}
#region Excel文件处理
void GetAllExcelPath()
{
EditorTools.CreateDirectory(Application.dataPath + "/Resources/ExcelData/Excel");
EditorTools.CreateDirectory(Application.dataPath + "/Resources/ExcelData/CSharpPath");
EditorTools.CreateDirectory(Application.dataPath + "/Resources/ExcelData/ExcelToJson");
string loPath = Application.dataPath + "/Resources/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("生成成功");
}
/// <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 = UnityEngine.Application.dataPath + "/Resources/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
{
//Debug.Log(data.Tables[i].Rows[rowNum][columnNum].ToString() + "\n");
table[columnNum] = data.Tables[i].Rows[rowNum][columnNum].ToString();
}
}
if (rowNum > 3)
{
//将一行数据存入list
ExcelDateList.Add(table);
}
}
CreatJsonFile();
//CreatCSharp(tableName);
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];
}
}
Debug.LogError(*);
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);
}
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();
}));
writer.Flush();
writer.Close();
//System.Diagnostics.Process.Start("explorer.exe", JsonPath.Replace("/", "\\"));
}
#endregion
//#region 创建C#代码
//void CreatCSharp(string name)
//{
// CSharpPath = UnityEngine.Application.dataPath + "/Resources/ExcelData/CSharpPath/" + name + ".cs";
// if (File.Exists(CSharpPath)) File.Delete(CSharpPath);
// //CodeTypeDeclaration 代码类型声明类
// CodeTypeDeclaration CSharpClass = new CodeTypeDeclaration(name);
// CSharpClass.IsClass = true;
// CSharpClass.TypeAttributes = TypeAttributes.Public;
// //设置成员的自定义属性
// //CodeAttributeDeclaration代码属性声明
// //CodeTypeReference代码类型引用类
// //System.Serializable 给脚本打上[System.Serializable()]标签,将 成员变量 在Inspector中显示
// CSharpClass.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference("System.Serializable")));
// for (int i = 0; i < dataName.Count; i++)
// {
// // 创建字段
// //CodeMemberField 代码成员字段类 => (Type, string name)
// CodeMemberField member = new CodeMemberField(GetTypeForExcel(dataType[i]), dataName[i] + ";//" + dataDoc[i]);
// member.Attributes = MemberAttributes.Public;
// CSharpClass.Members.Add(member);
// }
// // 获取C#语言的实例
// CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
// //代码生成器选项类
// CodeGeneratorOptions options = new CodeGeneratorOptions();
// //设置支撑的样式
// options.BracingStyle = "C";
// //在成员之间插入空行
// options.BlankLinesBetweenMembers = true;
// StreamWriter writer = new StreamWriter(CSharpPath, false, Encoding.GetEncoding("UTF-8"));
// //生成最终代码
// provider.GenerateCodeFromType(CSharpClass, writer, options);
// writer.Flush();
// writer.Close();
// //System.Diagnostics.Process.Start("explorer.exe", CSharpPath.Replace("/", "\\"));
//}
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 + "/Resources/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 = "_Scripts/ExcelData.cs";
private static string classTemp =
@"
using System.Collections.Generic;
using UnityEngine;
namespace ZXKFramework
{
public class ExcelData
{
//@ShuXing
public void Init()
{
//@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($"all{dataName} = ExcelDataTools.GetDataList<{dataName}>();");
string fangFaBase = @"
public # Get#(int id)
{
for (int i = 0; i < all#.Count; i++)
{
if (all#[i].id == id)
{
return all#[i];
}
}
Debug.LogError(id);
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);
}
string path = Path.Combine(Application.dataPath, classPath);
File.WriteAllText(path, codeClass, Encoding.UTF8);
Debug.Log($"ExcelData生成完毕");
}
}
}