ExcelToXml.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. using Excel;
  2. using PublicTools.XMLDataBase;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Data;
  6. using System.IO;
  7. using System.Linq;
  8. using UnityEditor;
  9. using UnityEngine;
  10. namespace XRTool.Util
  11. {
  12. /// <summary>
  13. /// Execl转XML对象文件
  14. /// </summary>
  15. public class ExcelToXml : EditorWindow
  16. {
  17. /// <summary>
  18. /// excel文件路径
  19. /// </summary>
  20. private string excelPath = "External/Studio2配置表.xlsx";
  21. /// <summary>
  22. /// 输出路径
  23. /// </summary>
  24. //private string outPath;
  25. /// <summary>
  26. /// 转化的对象名称
  27. /// </summary>
  28. //private string objectName;
  29. /// <summary>
  30. /// 转化规则
  31. /// 键值对分别采用','和'|'分割
  32. /// 例如 1,PriKey|3,Message
  33. /// </summary>
  34. private string rule = "0,PriKey|2,Message|3,AudioPath";
  35. private int startRow = 1;
  36. private bool isReadEnd;
  37. private int endRow = int.MaxValue;
  38. /// <summary>
  39. /// 强制更新
  40. /// </summary>
  41. private bool isForeceUpdate;
  42. [MenuItem("XRTools/ExcelToXML")]
  43. static void ExcelToXML()
  44. {
  45. if (BuildConfigMgr.Instance.IsInit)
  46. {
  47. if (BuildConfig.Instance)
  48. {
  49. ExcelToXml bw = GetWindow(typeof(ExcelToXml), false, "Excel转XML", true) as ExcelToXml;
  50. bw.ShowPopup();
  51. bw.autoRepaintOnSceneChange = true;
  52. }
  53. }
  54. }
  55. /// <summary>
  56. /// 转换器
  57. /// </summary>
  58. private void OnGUI()
  59. {
  60. if (!BuildConfigMgr.Instance.IsInit)
  61. {
  62. return;
  63. }
  64. ///Excel的路径
  65. excelPath = EditorGUILayout.TextField("Excel路径", excelPath);
  66. ///输出路径
  67. BuildConfig.Instance.languagePath = EditorGUILayout.TextField("输出路径",
  68. BuildConfig.Instance.languagePath);
  69. //objectName = EditorGUILayout.TextField("转化对象", objectName);
  70. //targetObj = EditorGUILayout.ObjectField("转化对象", targetObj, typeof(UnityEngine.Object), null) as UnityEngine.Object;
  71. rule = EditorGUILayout.TextField("转化规则", rule);
  72. startRow = EditorGUILayout.IntField("起始行", startRow);
  73. isReadEnd = EditorGUILayout.BeginToggleGroup("启用终止行", isReadEnd);
  74. endRow = EditorGUILayout.IntField("终止行", endRow);
  75. EditorGUILayout.EndToggleGroup();
  76. BuildConfig.Instance.prefix = EditorGUILayout.TextField("主键前缀", BuildConfig.Instance.prefix);
  77. isForeceUpdate = EditorGUILayout.ToggleLeft("强制刷新", isForeceUpdate);
  78. ///刷新指定路径下的所有资源的标签
  79. if (GUILayout.Button("转换", GUILayout.Width(100)))
  80. {
  81. ConversionToXML();
  82. }
  83. }
  84. /// <summary>
  85. /// 开始转换
  86. /// </summary>
  87. public void ConversionToXML()
  88. {
  89. string path = Application.dataPath;
  90. path = path.Substring(0, path.Length - ("Assets".Length + 1));
  91. path = path + "/" + excelPath;
  92. if (!File.Exists(path))
  93. {
  94. UnityLog.Instance.LogError(path + " is null");
  95. return;
  96. }
  97. ///打开或者创建Excel
  98. FileStream stream = File.Open(path, FileMode.OpenOrCreate);
  99. IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
  100. DataSet dataSet = excelReader.AsDataSet();
  101. stream.Close();
  102. excelReader.Close();
  103. if (dataSet == null)
  104. {
  105. UnityLog.Instance.LogError(path + " 读取失败!");
  106. stream.Close();
  107. excelReader.Close();
  108. return;
  109. }
  110. ///获取列
  111. DataColumnCollection columns = dataSet.Tables[0].Columns;
  112. ///获取行
  113. DataRowCollection rows = dataSet.Tables[0].Rows;
  114. ///解析出对应的元素,元素包含要解析的列和对应的映射
  115. List<string> elementList = new List<string>(rule.Split('|'));
  116. Dictionary<int, string> elementHash = new Dictionary<int, string>();
  117. for (int i = 0; i < elementList.Count; i++)
  118. {
  119. ///对应的列和映射的key
  120. string[] keys = elementList[i].Split(',');
  121. elementHash.Add(int.Parse(keys[0]), keys[1]);
  122. }
  123. foreach (var item in elementHash)
  124. {
  125. UnityLog.Instance.Log(item.Key + "" + item.Value);
  126. }
  127. ///每一行取指定列
  128. int maxRow = isReadEnd && endRow < rows.Count ? endRow : rows.Count;
  129. //List<Dictionary<string, string>> excelData = new List<Dictionary<string, string>>();
  130. string realDataPath = Path.Combine(Application.streamingAssetsPath, BuildConfig.Instance.languagePath);
  131. if (!Directory.Exists(realDataPath))
  132. {
  133. Directory.CreateDirectory(realDataPath);
  134. }
  135. //return;
  136. //MySql.WorkPath = realDataPath;
  137. try
  138. {
  139. //bool isOpen = MySql.Open<LanguageConf>(true);
  140. if (true)
  141. {
  142. //Debug.Log( dataSet.Tables[0].Rows[0][elementHash[0]].ToString());
  143. string languagePack = dataSet.Tables[0].Rows[0][elementHash.Keys.ToArray()[1]].ToString();
  144. LanguagePackConf conf = AutoAddPack(realDataPath, languagePack);
  145. if (conf == null)
  146. {
  147. UnityLog.Instance.LogError("转换语言包失败" + languagePack);
  148. return;
  149. }
  150. string tableName = typeof(LanguageConf).Name;
  151. XSql.Instance.CloseTable(tableName);
  152. var table = XSql.Instance.OpenTable(realDataPath + "/" + conf.PackagePath, tableName, ".xml", true);
  153. if (!table.Open())
  154. {
  155. table.Create(tableName);
  156. }
  157. for (int i = startRow; i < maxRow; i++)
  158. {
  159. ///以行为单位开始遍历取值
  160. Dictionary<string, string> valuePairs = new Dictionary<string, string>();
  161. foreach (var item in elementHash)
  162. {
  163. //Debug.Log(item.Value + " -- " + dataSet.Tables[0].Rows[i][item.Key].ToString());
  164. string keyValue = dataSet.Tables[0].Rows[i][item.Key].ToString();
  165. if (string.IsNullOrEmpty(keyValue))
  166. {
  167. break;
  168. }
  169. if (item.Value == "PriKey")
  170. {
  171. int num = -1;
  172. if (int.TryParse(keyValue, out num))
  173. {
  174. keyValue = BuildConfig.Instance.prefix + keyValue;
  175. }
  176. }
  177. valuePairs.Add(item.Value, keyValue);
  178. }
  179. //excelData.Add(valuePairs);
  180. LanguageConf t = ClazzFactory.ClazzPack<LanguageConf>(valuePairs);
  181. if (t == null)
  182. {
  183. UnityLog.Instance.LogError(i + " cant insert!");
  184. continue;
  185. }
  186. table.InsertData(t);
  187. }
  188. table.Close();
  189. }
  190. else
  191. {
  192. Debug.LogError("Error open " + realDataPath);
  193. }
  194. }
  195. catch (Exception ex)
  196. {
  197. Debug.LogError(ex.ToString());
  198. }
  199. //MySql.Close();
  200. AssetDatabase.Refresh();
  201. }
  202. public LanguagePackConf AutoAddPack(string path, string key)
  203. {
  204. string[] msg = key.Split('/');
  205. string tableName = typeof(LanguagePackConf).Name;
  206. var table = XSql.Instance.OpenTable(path, tableName, ".xml", true);
  207. if (!table.Open())
  208. {
  209. table.Create(tableName);
  210. }
  211. LanguagePackConf pack = table.FindData<LanguagePackConf>(key);
  212. if (pack == null)
  213. {
  214. pack = new LanguagePackConf();
  215. pack.Language = msg[0];
  216. pack.PackagePath = msg[1];
  217. table.InsertData(pack);
  218. }
  219. else
  220. {
  221. table.UpdateData(pack);
  222. }
  223. table.Save();
  224. return pack;
  225. }
  226. }
  227. }