Files
plugin-library/Assets/05.TableTextConversion/Editor/ConvertedExslDataMessage.cs
zhangzheng f9604896d5 1111
2025-11-17 14:48:50 +08:00

533 lines
21 KiB
C#
Raw 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;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using Excel;
using UnityEditor;
using UnityEngine;
using Sirenix.OdinInspector;
using Sirenix.OdinInspector.Editor;
using System.Linq;
using Newtonsoft.Json;
using Stary.Evo.TableTextConversion;
using UnityEngine.Serialization;
namespace Stary.Evo.TableTextConversion
{
public class ConvertedExslDataMessage : OdinEditorWindow
{
/// <summary>
/// 配置文件类型
/// </summary>
[EnumToggleButtons, HideLabel] [OnValueChanged("SetConfigurationFileType")]
public ConfigurationFileType configurationFileType = ConfigurationFileType.Asset;
private static ConvertedExslDataMessage window;
// 读取的位置
private static string DocFolderPath;
// 生成配置文件的位置
private static string Assetpath;
// 转化表的名称
private static string newDataName;
[MenuItem("Evo/Utility/PlayerPrefsClear")]
private static void PlayerPrefsClear()
{
PlayerPrefs.DeleteAll();
EditorPrefs.DeleteAll();
}
[MenuItem("Evo/Exsl配置表/信息表转换")]
static void ShowWindows()
{
window = (ConvertedExslDataMessage)EditorWindow.GetWindow(typeof(ConvertedExslDataMessage));
// 添加空值检查确保selectedDomainNames不会为null
window.selectedDomainNames = EditorPrefs.GetString("CurrentModulesName", "");
window.configurationFileType = (ConfigurationFileType)Enum.Parse(typeof(ConfigurationFileType),
EditorPrefs.GetString("ConfigurationFileType"));
window.Show();
}
[Title("转化配置的Exsl文件", titleAlignment: TitleAlignments.Centered)]
[HorizontalGroup("BuildPipeline"), HideLabel]
[ValueDropdown("GetBuildExslNames")]
[OnValueChanged("SetBuildExslNames")]
public string selectedExslNames;
[Title("转化文件存储的作用域:", titleAlignment: TitleAlignments.Centered)]
[HorizontalGroup("BuildPipeline"), HideLabel]
[ValueDropdown("GetCreatDomainAllName")]
[OnValueChanged("SetCurrentDomainName")]
public string selectedDomainNames;
#region
//[MenuItem("Exsl/信息表转换")]
[Button("转化Exsl表格", ButtonSizes.Large)]
public void CrtateMessage()
{
#region Excel表格并转成DataSet类型的数据
if (DocFolderPath == null)
{
Debug.LogError("UnityEvo:请先选择Exsl文件");
return;
}
if (Assetpath == null)
{
Debug.LogError("UnityEvo:请先选择生成配置文件的位置");
return;
}
/*if (!Directory.Exists(DocFolderPath))
{
Debug.LogError("UnityEvo:Exsl文件不存在");
return;
}*/
if (!Directory.Exists(Assetpath))
{
Debug.LogError("UnityEvo:生成配置文件的位置不存在");
return;
}
FileStream stream = File.Open(DocFolderPath, FileMode.Open, FileAccess.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
//获取结果
DataSet result = excelReader.AsDataSet();
if (result.Tables.Count > 0)
{
for (int i = 0; i < result.Tables.Count; i++)
{
var table = result.Tables[i];
//开始遍历说有table表
int oneRows = table.Rows.Count; //行数
Dictionary<int, int> dict_Question = new Dictionary<int, int>();
Dictionary<int, int> dict_Menu = new Dictionary<int, int>();
#region
int VoiceCount = 0;
for (int j = 0; j < oneRows; j++)
{
// string key = FilterTo(table.Rows[j][0].ToString());
// if (!string.IsNullOrEmpty(key))
// {
if (table.Rows[j].ItemArray.Length > 0 &&
!string.IsNullOrEmpty(FilterTo(table.Rows[j][0].ToString())))
{
VoiceCount++;
}
// }
}
#endregion
#region AudioTableData
if (table.TableName.ToLower().Contains("au"))
{
#region
List<AudioEntity> messageInfos = new List<AudioEntity>();
for (int j = 1; j < VoiceCount; j++)
{
AudioEntity messageInfo = new AudioEntity();
//获取对话块
messageInfo.index = j - 1;
//文件名称
messageInfo.auid = FilterTo(table.Rows[j][0].ToString());
//获取内容
messageInfo.autype =
Enum.TryParse(FilterTo(table.Rows[j][1].ToString()),
out AudioType auType)
? auType
: AudioType.Null;
//获取描述
messageInfo.filename = FilterTo(table.Rows[j][2].ToString());
messageInfo.voice = FilterTo(table.Rows[j][3].ToString());
messageInfo.uirelated = FilterTo(table.Rows[j][4].ToString());
//添加数据
messageInfos.Add(messageInfo);
}
#endregion
if (configurationFileType == ConfigurationFileType.Asset)
{
ScriptObjectSave<AudioTableData>("AudioTableData", (data) =>
{
data.infos = new List<AudioEntity>();
data.infos = messageInfos;
});
}
else if (configurationFileType == ConfigurationFileType.Json)
{
JsonSave<List<AudioEntity>>("AudioTableData", () => { return messageInfos; });
}
}
#endregion
#region VideoTableData
if (table.TableName.ToLower().Contains("vid"))
{
#region
List<VideoEntity> messageInfos = new List<VideoEntity>();
for (int j = 1; j < VoiceCount; j++)
{
VideoEntity messageInfo = new VideoEntity();
//获取对话块
messageInfo.index = j - 1;
//文件名称
messageInfo.vidid = FilterTo(table.Rows[j][0].ToString());
//获取内容
messageInfo.filename = FilterTo(table.Rows[j][1].ToString());
//获取描述
messageInfo.vidtype = FilterTo(table.Rows[j][2].ToString());
messageInfo.location = FilterTo(table.Rows[j][3].ToString());
messageInfo.time =
float.TryParse(FilterTo(table.Rows[j][4].ToString()), out float start)
? start
: 0;
messageInfo.subtitle = FilterTo(table.Rows[j][5].ToString()).Equals("是")
? true
: false;
messageInfo.videoframeName = FilterTo(table.Rows[j][6].ToString());
//添加数据
messageInfos.Add(messageInfo);
}
#endregion
if (configurationFileType == ConfigurationFileType.Asset)
{
ScriptObjectSave<VideoTableData>("VideoTableData", (data) =>
{
data.infos = new List<VideoEntity>();
data.infos = messageInfos;
});
}
else if (configurationFileType == ConfigurationFileType.Json)
{
JsonSave<List<VideoEntity>>("VideoTableData", () => { return messageInfos; });
}
}
#endregion
#region UITableData
if (table.TableName.ToLower().Contains("ui"))
{
#region
List<UIEntity> messageInfos = new List<UIEntity>();
UIEntity messageInfo = null;
List<SubtitleInfo> subtitle = null;
int infoIndex = 0;
for (int j = 1; j < VoiceCount; j++)
{
Debug.Log(j);
if (!table.Rows[j][0].ToString().Equals(""))
{
Debug.Log(table.Rows[j][0].ToString());
messageInfo = new UIEntity();
subtitle = new List<SubtitleInfo>();
messageInfo.subtitle = subtitle;
//获取对话块
messageInfo.index = infoIndex;
//文件名称
messageInfo.uiid = FilterTo(table.Rows[j][0].ToString());
//获取内容
messageInfo.filename = FilterTo(table.Rows[j][1].ToString());
//获取描述
messageInfo.uitype = FilterTo(table.Rows[j][2].ToString());
if (!table.Rows[j][3].ToString().Equals(""))
{
var subtitleInfo = new SubtitleInfo();
subtitleInfo.lineid = FilterTo(table.Rows[j][3].ToString());
subtitleInfo.subtitle = FilterTo(table.Rows[j][4].ToString());
subtitleInfo.start =
float.TryParse(FilterTo(table.Rows[j][5].ToString()),
out float start)
? start
: 0;
subtitleInfo.end = float.TryParse(FilterTo(table.Rows[j][6].ToString()),
out float end)
? end
: 0;
messageInfo.subtitle.Add(subtitleInfo);
}
//添加数据
messageInfos.Add(messageInfo);
infoIndex++;
}
else
{
if (!table.Rows[j][3].ToString().Equals(""))
{
var subtitleInfo = new SubtitleInfo();
subtitleInfo.lineid = FilterTo(table.Rows[j][3].ToString());
subtitleInfo.subtitle = FilterTo(table.Rows[j][4].ToString());
subtitleInfo.start =
float.TryParse(FilterTo(table.Rows[j][5].ToString()),
out float start)
? start
: 0;
subtitleInfo.end = float.TryParse(FilterTo(table.Rows[j][6].ToString()),
out float end)
? end
: 0;
messageInfo.subtitle.Add(subtitleInfo);
}
}
}
#endregion
if (configurationFileType == ConfigurationFileType.Asset)
{
ScriptObjectSave<UITableData>("UITableData", (data) =>
{
data.infos = new List<UIEntity>();
data.infos = messageInfos;
});
}
else if (configurationFileType == ConfigurationFileType.Json)
{
JsonSave<List<UIEntity>>("UITableData", () => { return messageInfos; });
}
}
#endregion
#endregion
}
}
}
/// <summary>
/// 过滤:去掉首尾空格和换行符【\n】
/// </summary>
private static string FilterTo(string self)
{
self = self.TrimStart();
self = self.TrimEnd();
self = self.Replace("\n", "");
return self;
}
/// <summary>
/// ScriptObject数据保存类
/// </summary>
/// <param name="assetName"></param>
/// <param name="action">写入数据的一个回调</param>
/// <typeparam name="T"></typeparam>
private static void ScriptObjectSave<T>(string assetName, Action<T> action) where T : ScriptableObject
{
string jsonPath = $"{Assetpath}{assetName}.asset";
if (File.Exists(jsonPath))
{
EditorFrameworkUtils.DeleteFile(Assetpath, assetName + ".asset");
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
jsonPath = jsonPath.Substring(jsonPath.IndexOf("Assets"));
// Debug.Log($"要创建的为{jsonPath}");
var data = ScriptableObject.CreateInstance<T>();
//放写入数据操作
action.Invoke(data);
AssetDatabase.CreateAsset(data, jsonPath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
/// <summary>
/// ScriptObject数据保存类
/// </summary>
/// <param name="assetName"></param>
/// <param name="action">写入数据的一个回调</param>
/// <typeparam name="T"></typeparam>
private static void JsonSave<T>(string assetName, Func<T> func) where T : IEnumerable, new()
{
// 创建数据实例
T data = new T();
//放写入数据操作
data = func.Invoke();
// 确保保存目录存在
if (!Directory.Exists(Assetpath))
{
Directory.CreateDirectory(Assetpath);
}
// 构建完整的保存路径
string jsonFilePath = Path.Combine(Assetpath, $"{assetName}.json");
// 序列化数据为JSON
string jsonContent = JsonConvert.SerializeObject(data, Formatting.Indented);
// 写入文件
File.WriteAllText(jsonFilePath, jsonContent);
// 刷新AssetDatabase
AssetDatabase.Refresh();
Debug.Log($"UnityEvo: JSON文件已保存到 {jsonFilePath}");
}
#endregion
/// <summary>
/// 获取Doc文件夹的路径
/// </summary>
/// <returns></returns>
private string GetDocFolderPath()
{
// 获取 Assets 文件夹的路径
string assetsPath = Application.dataPath;
// 获取项目的根目录路径
string projectRootPath = Path.GetDirectoryName(assetsPath);
// 构造 Doc 文件夹的路径
string docFolderPath = Path.Combine(projectRootPath, "Doc");
return docFolderPath;
}
/// <summary>
/// 获取Doc文件夹下所有的Exsl名
/// </summary>
/// <returns></returns>
private List<string> GetBuildExslNames()
{
string docFolderPath = GetDocFolderPath();
// 检查 Doc 文件夹是否存在
if (!Directory.Exists(docFolderPath))
{
Debug.LogError($"UnityEvo:Doc 文件夹不存在,请检查路径:{docFolderPath}");
return null;
}
List<string> result = new List<string>();
result.Add("null");
// 遍历 Doc 文件夹中的所有 .xlsx 文件
string[] xlsxFiles = Directory.GetFiles(docFolderPath, "*.xlsx");
result.AddRange(xlsxFiles.Select(file => Path.GetFileNameWithoutExtension(file)).ToList());
selectedExslNames = EditorPrefs.GetString("BuildExslNames");
return result;
}
private void SetBuildExslNames(string newValue)
{
DocFolderPath = Path.Combine(GetDocFolderPath(), newValue + ".xlsx");
newDataName = newValue;
EditorPrefs.SetString("BuildExslNames", newDataName);
}
/// <summary>
/// 获取全部作用域名
/// </summary>
public List<string> GetCreatDomainAllName()
{
string domainPath = "";
if (configurationFileType == ConfigurationFileType.Asset)
{
domainPath = $"{Application.dataPath}/Domain";
}
else if (configurationFileType == ConfigurationFileType.Json)
{
domainPath = $"{Application.dataPath}/Modules";
}
List<string> domains = new List<string>();
domains.Add("null");
// 新增目录获取代码
if (Directory.Exists(domainPath))
{
var dirInfo = new DirectoryInfo(domainPath);
// 获取直接子目录(不递归)
domains.AddRange(dirInfo.GetDirectories("*", SearchOption.TopDirectoryOnly)
.Select(d => d.Name).ToList());
}
if (configurationFileType == ConfigurationFileType.Asset)
{
selectedDomainNames = EditorPrefs.GetString("CurrentDomainName");
}
else if (configurationFileType == ConfigurationFileType.Json)
{
selectedDomainNames = EditorPrefs.GetString("CurrentModulesName");
}
return domains.ToList();
}
private void SetCurrentDomainName(string newValue)
{
if (configurationFileType == ConfigurationFileType.Asset)
{
Assetpath = Application.dataPath + "/Domain/" + newValue + "/AddressableRes/Config/";
string valueToSave = string.IsNullOrEmpty(selectedDomainNames) ? "" : selectedDomainNames;
EditorPrefs.SetString("CurrentDomainName", valueToSave);
}
else
{
Assetpath = Application.dataPath + "/Modules/" + newValue + "/Main/Res/Config/";
string valueToSave = string.IsNullOrEmpty(selectedDomainNames) ? "" : selectedDomainNames;
EditorPrefs.SetString("CurrentModulesName", valueToSave);
}
if (!Directory.Exists(Assetpath))
{
Directory.CreateDirectory(Assetpath);
}
}
private void SetConfigurationFileType()
{
EditorPrefs.SetString("ConfigurationFileType", configurationFileType.ToString());
}
}
public enum ConfigurationFileType
{
/// <summary>
/// json类型
/// </summary>
Json,
/// <summary>
/// asset类型
/// </summary>
Asset
}
}