| 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<int> m_FitterCols = new List<int>(); | 
|     List<string> m_FitterKeys = new List<string>(); | 
|     public Dictionary<string, string> m_Englishs = new Dictionary<string, string>(); | 
|     public Dictionary<string, string> m_EnglishReplaces = new Dictionary<string, string>(); | 
|     public Dictionary<FileInfo, string> m_AllTexts = new Dictionary<FileInfo, string>(); | 
|     [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, "</r>", string.Empty); | 
|             _check = Regex.Replace(_check, "<color=#[a-zA-Z0-9]+>", string.Empty); | 
|             _check = Regex.Replace(_check, "</color>", string.Empty); | 
|             _check = Regex.Replace(_check, "<size=[0-9]+>", string.Empty); | 
|             _check = Regex.Replace(_check, "</size>", string.Empty); | 
|             _check = Regex.Replace(_check, "<Word (.*?)/>", string.Empty); | 
|             _check = Regex.Replace(_check, "<Img (.*?)/>", string.Empty); | 
|             _check = Regex.Replace(_check, "<a>(.*?)</a>", string.Empty); | 
|             _check = Regex.Replace(_check, "<Space=([0-9]*)>", 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<Match> _list = new List<Match>(); | 
|                 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); | 
|     } | 
| } |