ExportConfig.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. using UnityEditor;
  2. using UnityEngine;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using Excel;
  7. using System.Data;
  8. using System.Xml;
  9. public class ExportConfig : EditorWindow
  10. {
  11. [MenuItem("QHJ/Design Tools/Export Config")]
  12. public static void AddWindow()
  13. {
  14. Rect wr = new Rect(0, 0, 350, 220);
  15. ExportConfig window = (ExportConfig)EditorWindow.GetWindowWithRect(typeof(ExportConfig), wr, false, "Export Config");
  16. window.Show();
  17. }
  18. public List<string> nameArray = new List<string>();
  19. private string defaultPath;
  20. private bool shouldDelete = true, ignoreSameVersion = true;
  21. private bool isSuccess;
  22. private string text;
  23. private List<string> idArr;
  24. private Dictionary<string, string> md5Dict;
  25. void Awake()
  26. {
  27. defaultPath = Application.dataPath + @"/XlsxSource";
  28. if (!Directory.Exists(defaultPath))
  29. Directory.CreateDirectory(defaultPath);
  30. GetObjectNameToArray<string>(defaultPath, "xlsx");
  31. }
  32. void OnGUI()
  33. {
  34. EditorGUI.LabelField(new Rect(90, 50, 200, 16), new GUIContent("导出所有配置文件到xml目录"));
  35. shouldDelete = EditorGUI.Toggle(new Rect(90, 80, 200, 16), new GUIContent("覆盖已有文件"), shouldDelete);
  36. ignoreSameVersion = EditorGUI.Toggle(new Rect(90, 100, 200, 16), new GUIContent("忽略相同版本"), ignoreSameVersion);
  37. EditorGUI.LabelField(new Rect(2, 200, 350, 16), new GUIContent("Chongqing Challeng Tech. Co.,Ltd, gsgundam, v0.1.0"));
  38. if (GUI.Button(new Rect(50, 135, 250, 40), "立即导出"))
  39. CreateAllXml();
  40. }
  41. /// <summary>
  42. /// Return all files' name in target path in Assets//
  43. /// </summary>
  44. /// <returns>File name in array</returns>
  45. /// <param name="path">Assets sublevel path</param>
  46. /// <param name="pattern">File type filter</param>
  47. /// <typeparam name="T">Class name</typeparam>
  48. void GetObjectNameToArray<T>(string path, string pattern, string subDirectory = "")
  49. {
  50. try
  51. {
  52. //return file name by array in target folder & subfolder, it can be null
  53. string[] files = Directory.GetFiles(path);
  54. for (int i = 0; i < files.Length; i++)
  55. {
  56. string p = files[i];
  57. //file
  58. int index = p.LastIndexOf("\\");
  59. string folder = p.Substring(0, index + 1);
  60. string fileName = p.Substring(index + 1);
  61. //if directoryEntries is not null, tempPaths cannot be null after splited
  62. if (fileName.EndsWith(".meta"))
  63. continue;
  64. string[] pathSplit = StringExtention.SplitWithString(fileName, ".");
  65. if (pathSplit.Length > 1)
  66. {
  67. nameArray.Add(subDirectory + "\\" + pathSplit[0]);
  68. }
  69. }
  70. //recursion
  71. string[] folders = Directory.GetDirectories(path);
  72. for (int i = 0; i < folders.Length; i++)
  73. {
  74. string p = folders[i];
  75. GetObjectNameToArray<T>(p, pattern, p.Substring(defaultPath.Length));
  76. }
  77. }
  78. catch (System.IO.DirectoryNotFoundException)
  79. {
  80. Debug.Log("The path encapsulated in the " + path + "Directory object does not exist.");
  81. }
  82. }
  83. /// <summary>
  84. /// custom split string function
  85. /// </summary>
  86. private class StringExtention
  87. {
  88. public static string[] SplitWithString(string sourceString, string splitString)
  89. {
  90. string tempSourceString = sourceString;
  91. List<string> arrayList = new List<string>();
  92. string s = string.Empty;
  93. while (sourceString.IndexOf(splitString) > -1) //split
  94. {
  95. s = sourceString.Substring(0, sourceString.IndexOf(splitString));
  96. sourceString = sourceString.Substring(sourceString.IndexOf(splitString) + splitString.Length);
  97. arrayList.Add(s);
  98. }
  99. arrayList.Add(sourceString);
  100. return arrayList.ToArray();
  101. }
  102. }
  103. private void CreateAllXml()
  104. {
  105. foreach (string str in nameArray)
  106. {
  107. Debug.Log(str);
  108. if (str.Contains("xlsx_md5") || str.Contains("language"))
  109. continue;
  110. if (ignoreSameVersion)
  111. {
  112. GetMd5Xml(str);
  113. if (!CheckVersion(str))
  114. {
  115. CreateXml(str);
  116. }
  117. }
  118. else
  119. {
  120. CreateXml(str);
  121. }
  122. }
  123. if (isSuccess)
  124. {
  125. ShowNotification(new GUIContent( "已成功导出!"));
  126. DirectoryInfo di = new DirectoryInfo(defaultPath);
  127. DirectoryInfo[] diArr = di.GetDirectories();
  128. for (int i = 0; i < diArr.Length; i++)
  129. CreateMd5XML(diArr[i].ToString() + "/");
  130. AssetDatabase.Refresh();
  131. }
  132. else
  133. ShowNotification(new GUIContent("文件有错误!"));
  134. }
  135. private void CreateXml(string fileName)
  136. {
  137. idArr = new List<string>();
  138. // string filepath = Application.dataPath + @"/Resources/XML/Config" + fileName + ".xml";
  139. string filepath = Application.dataPath + @"/Resources/XML/Config" + fileName + ".xml";
  140. text = "";
  141. filepath = filepath.Replace("\\", "/");
  142. string[] pathArr = filepath.Split('/');
  143. string tempPath = "";
  144. for(int i = 0; i < pathArr.Length; i++)
  145. {
  146. tempPath += pathArr[i] + "/";
  147. if (i > 1 && i < pathArr.Length - 1)
  148. {
  149. if (!Directory.Exists(tempPath))
  150. {
  151. Directory.CreateDirectory(tempPath);
  152. }
  153. }
  154. }
  155. if ((!File.Exists(filepath) && !shouldDelete) || shouldDelete)
  156. {
  157. List<string> labels = new List<string>(), comments = new List<string>();
  158. XmlDocument xmlDoc = new XmlDocument();
  159. try
  160. {
  161. FileStream stream = File.Open(Application.dataPath + @"/XlsxSource" + fileName + ".xlsx", FileMode.Open, FileAccess.Read);
  162. IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
  163. text += "\nexcelReader.ResultsCount is" + excelReader.ResultsCount + "\n";
  164. text += "start excelReader. \n";
  165. DataSet result = excelReader.AsDataSet();
  166. text += "get result successful? result[" + result + "]";
  167. text += "result columns count is " + result.Tables[0].Columns.Count;
  168. int columns = result.Tables[0].Columns.Count;
  169. int rows = result.Tables[0].Rows.Count;
  170. //start create xml
  171. XmlElement root = xmlDoc.CreateElement("data");
  172. XmlElement comment = xmlDoc.CreateElement("comment");
  173. for (int i = 0; i < rows; i++)
  174. {
  175. XmlElement item = xmlDoc.CreateElement("item");
  176. if (i == 0)
  177. {
  178. continue;
  179. }
  180. for (int j = 0; j < columns; j++)
  181. {
  182. string nvalue = result.Tables[0].Rows[i][j].ToString();
  183. if (i == 1)
  184. {
  185. if (nvalue != null && nvalue != "")
  186. labels.Add(nvalue);
  187. }
  188. else if (i == 2)
  189. {
  190. if (j < labels.Count)
  191. {
  192. XmlElement commentItem = xmlDoc.CreateElement(labels[j]);
  193. commentItem.InnerText = "\n" + nvalue + "\n";
  194. comment.AppendChild(commentItem);
  195. }
  196. }
  197. else if (j < labels.Count)
  198. {
  199. if (fileName.Contains("shop_config"))
  200. nvalue = nvalue.Replace("\n", "");
  201. item.SetAttribute(labels[j], nvalue);
  202. if(j == 0 && !StringUtil.Empty(nvalue))
  203. {
  204. //check duplicate
  205. CheckDuplicate(fileName, nvalue);
  206. idArr.Add(nvalue);
  207. }
  208. //Debug.Log("labels[j] is " + labels[j] + ", nvalue is " + nvalue);
  209. }
  210. //Debug.Log(nvalue);
  211. }
  212. if (i > 2 && (item.GetAttribute("id") != "" || fileName.Contains("word_config")))
  213. {
  214. root.AppendChild(item);
  215. }
  216. }
  217. root.AppendChild(comment);
  218. xmlDoc.AppendChild(root);
  219. xmlDoc.Save(filepath);
  220. AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
  221. // AssetDatabase.ImportAsset(@"Assets/Resources/XML/Config" + fileName + ".xml", ImportAssetOptions.ForceUpdate);
  222. //Debug.Log(fileName + ".xml is saved to " + filepath + ", count is " + idArr.Count);
  223. isSuccess = true;
  224. }
  225. catch (Exception e)
  226. {
  227. text += "Exception " + e.Message;
  228. Debug.Log("Exception " + e.Message);
  229. }
  230. }
  231. }
  232. private void CheckDuplicate(string fileName, string id)
  233. {
  234. if (fileName.Contains ("word_config"))
  235. return;
  236. if (idArr.Count < 1)
  237. return;
  238. for (int i = 0; i < idArr.Count; i++)
  239. {
  240. if (idArr[i] == id)
  241. Debug.LogError(id + " in " + fileName + " is a duplicate id.");
  242. }
  243. }
  244. private void HideNotification()
  245. {
  246. this.RemoveNotification();
  247. }
  248. private void CreateMd5XML(string sourcePath)
  249. {
  250. DirectoryInfo directoryInfo = new DirectoryInfo(sourcePath);
  251. List<string> pathList = DGFileUtil.GetAllFiles(directoryInfo, ".meta");
  252. XmlDocument xml = CreateMd5XmlDocument(pathList, sourcePath, null, null);
  253. string xmlSavePath = sourcePath + "xlsx_md5.xml";
  254. xml.Save(xmlSavePath);
  255. Debug.Log("Create xlsx xml : " + xmlSavePath);
  256. AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
  257. }
  258. private XmlDocument CreateMd5XmlDocument(List<string> pathList, string pathRoot, List<string> exceptList, string exceptRoot)
  259. {
  260. XmlDocument xml = new XmlDocument();
  261. XmlElement root = xml.CreateElement("xlsx");
  262. xml.AppendChild(root);
  263. for (int i = 0; i < pathList.Count; i++)
  264. {
  265. string assetPath = pathList[i];
  266. string md5 = MD5Util.GetFileHash(assetPath);
  267. string p = assetPath.Substring(pathRoot.Length);
  268. pathList[i] = p;
  269. XmlElement e = xml.CreateElement("a");
  270. XmlAttribute attr = xml.CreateAttribute("p");
  271. attr.Value = p;
  272. e.Attributes.Append(attr);
  273. attr = xml.CreateAttribute("m");
  274. attr.Value = md5;
  275. e.Attributes.Append(attr);
  276. root.AppendChild(e);
  277. }
  278. return xml;
  279. }
  280. private bool CheckVersion(string fileName)
  281. {
  282. if (md5Dict == null || md5Dict.Count < 1)
  283. return false;
  284. else
  285. {
  286. string[] pathArr = StringExtention.SplitWithString(fileName, "\\");
  287. if (pathArr.Length < 3)
  288. return false;
  289. string str = pathArr[2] + ".xlsx";
  290. string md5 = MD5Util.GetFileHash(defaultPath + fileName + ".xlsx");
  291. if (md5Dict.ContainsKey(str) && md5Dict[str] == md5)
  292. {
  293. Debug.Log(pathArr[2] + ".xlsx" + " has same version, ignored");
  294. return true;
  295. }
  296. else
  297. {
  298. if(md5Dict.ContainsKey(str))
  299. Debug.Log(fileName + ": [xml]" + md5Dict[str] + ", [xlsx]" + md5);
  300. else
  301. Debug.Log(fileName + "is new xlsx file, [xlsx]" + md5);
  302. }
  303. return false;
  304. }
  305. }
  306. private void GetMd5Xml(string fileName)
  307. {
  308. string[] pathArr = StringExtention.SplitWithString(fileName, "\\");
  309. string parent = pathArr[1];
  310. string xmlPath = defaultPath + "/" + parent + "/xlsx_md5.xml";
  311. if (!File.Exists(xmlPath))
  312. {
  313. return;
  314. }
  315. StreamReader sr = File.OpenText(xmlPath);
  316. string data = sr.ReadToEnd();
  317. sr.Close();
  318. sr.Dispose();
  319. XmlDocument xml = new XmlDocument();
  320. xml.LoadXml(data);
  321. md5Dict = new Dictionary<string, string>();
  322. XmlNode mapNode = xml.SelectSingleNode("xlsx");
  323. XmlNodeList nodeList = mapNode.SelectNodes("a");
  324. for (int i = 0; i < nodeList.Count; i++)
  325. {
  326. XmlNode node = nodeList[i];
  327. string path = node.Attributes["p"].Value;
  328. string md5 = node.Attributes["m"].Value;
  329. md5Dict.Add(path, md5);
  330. }
  331. }
  332. void OnInspectorUpdate()
  333. {
  334. this.Repaint();
  335. }
  336. void OnDestory()
  337. {
  338. EditorUtility.UnloadUnusedAssetsImmediate();
  339. }
  340. }