using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.IO; using System.Text; using System; using System.Text.RegularExpressions; public class ExcelParseTool : EditorWindow { [SerializeField] string filePath = string.Empty; [SerializeField] string replaceFilePath = string.Empty; [SerializeField] string cacheDirectory = string.Empty; protected string[] lineStep = new string[] { "\r\n" }; //行间隔体 public string[] m_Lines = null; FileInfo m_FileInfo; StringBuilder m_StringBuilder = new StringBuilder(); List m_FitterCols = new List(); List m_FitterKeys = new List(); public Dictionary m_Englishs = new Dictionary(); public Dictionary m_EnglishReplaces = new Dictionary(); public Dictionary m_AllTexts = new Dictionary(); [MenuItem("策划工具/Excel解析")] public static void OpenWindow() { ExcelParseTool _window = GetWindow(typeof(ExcelParseTool), false, "Excel解析") as ExcelParseTool; _window.Show(); _window.autoRepaintOnSceneChange = true; } private void OnGUI() { GUI.skin.button.normal.textColor = Color.white; GUILayout.BeginHorizontal(); GUILayout.Label(StringUtility.Contact("文件路径:", filePath)); if (GUILayout.Button("Browser")) { filePath = EditorUtility.OpenFolderPanel("文件路径", "", ""); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.Label(StringUtility.Contact("替换文件:", replaceFilePath)); if (GUILayout.Button("Browser")) { replaceFilePath = EditorUtility.OpenFilePanel("替换文件", "", ""); } if (GUILayout.Button("解析")) { m_Englishs.Clear(); ConfigInitiator.EditorLoad(); m_FitterKeys.Clear(); m_FitterKeys.AddRange(LanguageConfig.GetKeys()); m_FitterKeys.AddRange(SysInfoConfig.GetKeys()); m_FitterKeys.AddRange(IconConfig.GetKeys()); FindEnglishLabel(); } if (GUILayout.Button("替换")) { m_AllTexts.Clear(); try { var _fileInfo = new FileInfo(replaceFilePath); var fs = _fileInfo.OpenRead(); var sr = new StreamReader(fs, Encoding.UTF8); var lines = sr.ReadToEnd().Split(lineStep, StringSplitOptions.None); m_EnglishReplaces.Clear(); for (int i = 0; i < lines.Length; i++) { var _line = lines[i].Split('\t'); if (_line.Length > 1 && _line[1] != string.Empty) { m_EnglishReplaces.Add(_line[0], _line[1]); } } fs.Dispose(); fs.Close(); } catch (Exception e) { DebugEx.LogError(e.ToString()); } ConfigInitiator.EditorLoad(); m_FitterKeys.Clear(); m_FitterKeys.AddRange(LanguageConfig.GetKeys()); m_FitterKeys.AddRange(SysInfoConfig.GetKeys()); m_FitterKeys.AddRange(IconConfig.GetKeys()); FindEnglishLabel(true); } } void FindEnglishLabel(bool _replace = false) { string[] _files = Directory.GetFiles(filePath, "*.txt", SearchOption.AllDirectories); if (_files == null || _files.Length == 0) { return; } var _index = 0; EditorApplication.update += delegate () { var _fileInfo = new FileInfo(_files[_index]); m_FileInfo = _fileInfo; if (_fileInfo != null && (_fileInfo.Name == "Face.txt" || _fileInfo.Name == "ActorShow.txt" || _fileInfo.Name == "DirtyWord.txt" || _fileInfo.Name == "Audio.txt" || _fileInfo.Name == "Effect.txt" || _fileInfo.Name == "GmCmd.txt" || _fileInfo.Name == "Map.txt" || _fileInfo.Name == "Icon.txt" || _fileInfo.Name == "mapnpc.txt" || _fileInfo.Name == "Market.txt" || _fileInfo.Name == "PlayerProperty.txt" || _fileInfo.Name == "RichTextMsgReplace.txt" || _fileInfo.Name == "TablePath.txt" || _fileInfo.Name == "LoginSeverList.txt" || _fileInfo.Name == "FuncConfig.txt" || _fileInfo.Name == "logger.txt")) { } else { m_AllTexts.Add(m_FileInfo, string.Empty); try { var fs = m_FileInfo.OpenRead(); var sr = new StreamReader(fs, Encoding.UTF8); var lines = sr.ReadToEnd().Split(lineStep, StringSplitOptions.None); ParseExcel(lines, true); fs.Dispose(); fs.Close(); } catch (Exception e) { DebugEx.LogError(e.ToString()); } } bool isCancel = EditorUtility.DisplayCancelableProgressBar("查找英文", StringUtility.Contact(_index, "/", _files.Length), (float)_index / _files.Length); _index++; if (isCancel || _index >= _files.Length) { EditorApplication.update = null; EditorUtility.ClearProgressBar(); _index = 0; if (_replace) { foreach (var _key in m_AllTexts.Keys) { var _replaceInfo = new FileInfo(replaceFilePath); using (FileStream _fs = new FileStream(StringUtility.Contact(_replaceInfo.DirectoryName, "/", _key.Name), FileMode.Create, FileAccess.Write, FileShare.Write)) { using (StreamWriter sw = new StreamWriter(_fs, Encoding.UTF8)) { sw.Write(m_AllTexts[_key]); } } } return; } using (FileStream fs = new FileStream(StringUtility.Contact(filePath, "/PathCache/logger.txt"), FileMode.Create, FileAccess.Write, FileShare.Write)) { using (StreamWriter sw = new StreamWriter(fs)) { foreach (var item in m_Englishs.Values) { sw.WriteLine(item); } } } } }; } void ParseExcel(string[] lines, bool _replace = false) { m_FitterCols.Clear(); var _types = lines[0].Split('\t'); var _keys = lines[1].Split('\t'); m_FitterCols.Add(0); m_Lines = lines; for (int i = 0; i < _types.Length; i++) { if (m_FileInfo.Name == "NPC.txt" && _types[i] == "int[]") { m_FitterCols.Add(i); } if (_types[i] == "int" || _types[i] == "int[]") { m_FitterCols.Add(i); } } for (int i = 0; i < _keys.Length; i++) { if (m_FileInfo.Name == "NPC.txt" && _keys[i] == "MODE") { m_FitterCols.Add(i); } } for (int i = 0; i < lines.Length; i++) { if (i < 3) { if (_replace) { m_AllTexts[m_FileInfo] += lines[i]; m_AllTexts[m_FileInfo] += "\r\n"; } continue; } FindEnglish(lines[i], _replace); EditorUtility.DisplayCancelableProgressBar("", StringUtility.Contact(i, "/", lines.Length), (float)i / lines.Length); } if (_replace) { m_AllTexts[m_FileInfo] = m_AllTexts[m_FileInfo].Remove(m_AllTexts[m_FileInfo].Length - 2, 2); } } void FindEnglish(string line, bool _replace = false) { m_StringBuilder.Length = 0; var elements = line.Split('\t'); for (int i = 0; i < elements.Length; i++) { if (m_FitterCols.Contains(i)) { m_StringBuilder.Append(elements[i]); m_StringBuilder.Append('\t'); continue; } var _label = elements[i]; if (m_FitterKeys.Contains(_label.Trim())) { m_StringBuilder.Append(_label); m_StringBuilder.Append('\t'); continue; } var _check = Regex.Replace(_label, "", string.Empty); _check = Regex.Replace(_check, "", string.Empty); _check = Regex.Replace(_check, "", string.Empty); _check = Regex.Replace(_check, "", string.Empty); _check = Regex.Replace(_check, "", string.Empty); _check = Regex.Replace(_check, "", string.Empty); _check = Regex.Replace(_check, "", string.Empty); _check = Regex.Replace(_check, "(.*?)", string.Empty); _check = Regex.Replace(_check, "", string.Empty); _check = Regex.Replace(_check, "%s[0-9]+", string.Empty); MatchCollection _collection = Regex.Matches(_check, "[^a-zA-Z]*([a-zA-Z]+)[^a-zA-Z]*"); if (_collection.Count > 0) { List _list = new List(); for (int q = 0; q < _collection.Count; q++) { _list.Add(_collection[q] as Match); } _list.Sort(Compare); for (int q = 0; q < _list.Count; q++) { Match _match = _list[q]; if (m_FitterKeys.Contains(_match.Groups[1].Value)) { continue; } if (_replace) { if (m_EnglishReplaces.ContainsKey(_match.Groups[1].Value)) { _label = Regex.Replace(_label, _match.Groups[1].Value, m_EnglishReplaces[_match.Groups[1].Value]); } } else if (!m_Englishs.ContainsKey(_match.Groups[1].Value)) { m_Englishs.Add(_match.Groups[1].Value, StringUtility.Contact(m_FileInfo.Name, "\t", "id:\t", elements[0], "\t key:\t", m_Lines[1].Split('\t')[i].ToString(), "\t", _match.Groups[1].Value)); } } m_StringBuilder.Append(_label); m_StringBuilder.Append('\t'); } else { m_StringBuilder.Append(_label); m_StringBuilder.Append('\t'); } } m_StringBuilder.Remove(m_StringBuilder.Length - 1, 1); m_AllTexts[m_FileInfo] += m_StringBuilder.ToString(); m_AllTexts[m_FileInfo] += "\r\n"; } int Compare(Match x, Match y) { return -x.Groups[1].Value.Length.CompareTo(y.Groups[1].Value.Length); } }