ProcessExportAllViewModel.cs 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198
  1. using Aitex.Core.Backend;
  2. using Aitex.Core.RT.IOCore;
  3. using Aitex.Core.RT.Log;
  4. using DocumentFormat.OpenXml.Packaging;
  5. using DocumentFormat.OpenXml.Spreadsheet;
  6. using MECF.Framework.Common.CommonData.EnumData;
  7. using MECF.Framework.Common.ControlDataContext;
  8. using MECF.Framework.Common.DataCenter;
  9. using MECF.Framework.Common.Equipment;
  10. using MECF.Framework.Common.Utilities;
  11. using MECF.Framework.UI.Client.CenterViews.Configs.SystemConfig;
  12. using MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory;
  13. using MECF.Framework.UI.Client.CenterViews.Dialogs;
  14. using MECF.Framework.UI.Client.CenterViews.Operations.RealTime;
  15. using MECF.Framework.UI.Client.ClientBase;
  16. using NPOI.SS.UserModel;
  17. using NPOI.Util;
  18. using NPOI.XSSF.UserModel;
  19. using OpenSEMI.ClientBase;
  20. using SciChart.Charting.Visuals;
  21. using SciChart.Charting.Visuals.Annotations;
  22. using SciChart.Charting.Visuals.Axes;
  23. using SciChart.Charting.Visuals.RenderableSeries;
  24. using SciChart.Data.Model;
  25. using System;
  26. using System.Collections.Concurrent;
  27. using System.Collections.Generic;
  28. using System.Collections.ObjectModel;
  29. using System.Data;
  30. using System.Diagnostics;
  31. using System.Drawing;
  32. using System.IO;
  33. using System.Linq;
  34. using System.Text;
  35. using System.Threading;
  36. using System.Threading.Tasks;
  37. using System.Windows;
  38. using static MECF.Framework.Common.FAServices.DataVariables;
  39. using Action = System.Action;
  40. using Media = System.Windows.Media;
  41. namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
  42. {
  43. class ProcessExportAllViewModel<T> : ModuleUiViewModelBase where T : IComparable
  44. {
  45. private ProcessExportAllView view;
  46. private CancellationTokenSource _cancellationTokenSource;
  47. private event EventHandler Exporting;
  48. private const int MAX_PARAMETERS = 1000;
  49. public List<ProcessHistoryLot> RecipeDatas { get; set; }
  50. private ObservableCollection<ParameterNode> _ParameterNodes;
  51. public ObservableCollection<ParameterNode> ParameterNodes
  52. {
  53. get { return _ParameterNodes; }
  54. set { _ParameterNodes = value; NotifyOfPropertyChange("ParameterNodes"); }
  55. }
  56. private Dictionary<string, string> _processDetailDisplayDic = new Dictionary<string, string>();
  57. private Dictionary<string, Dictionary<string, string>> _processProcessDetailAttributeDict = new Dictionary<string, Dictionary<string, string>>();
  58. // public ObservableCollection<IRenderableSeries> SelectedData { get; set; }
  59. public ObservableCollection<ParameterNode> GetParameters()
  60. {
  61. ObservableCollection<ParameterNode> rootNode = new ObservableCollection<ParameterNode>();
  62. try
  63. {
  64. Dictionary<string, string> displayDic = QueryDataClient.Instance.Service.GetData("System.ProcessDetailDisplay") as Dictionary<string, string>;
  65. if (displayDic == null)
  66. return rootNode;
  67. List<string> dataList = new List<string>();
  68. foreach (var key in displayDic.Keys)
  69. {
  70. string[] item = key.Split('.');
  71. if (item != null)
  72. {
  73. if (item.Length == 2)
  74. {
  75. _processDetailDisplayDic.Add($"{item[1]}", displayDic[key]);
  76. dataList.Add($"{item[0]}.{item[1]}");
  77. }
  78. else if (item.Length == 3)
  79. {
  80. _processDetailDisplayDic.Add($"{item[1]} {item[2]}", displayDic[key]);
  81. dataList.Add($"{item[0]}.{item[1]}.{item[2]}");
  82. }
  83. }
  84. Dictionary<string, ParameterNode> indexer = new Dictionary<string, ParameterNode>();
  85. foreach (string dataName in dataList)
  86. {
  87. string[] nodeName = dataName.Split('.');
  88. ParameterNode parentNode = null;
  89. string pathName = "";
  90. for (int i = 0; i < nodeName.Length; i++)
  91. {
  92. pathName = (i == 0 || i == 1) ? nodeName[i] : (pathName + " " + nodeName[i]);
  93. if (!indexer.ContainsKey(pathName))
  94. {
  95. indexer[pathName] = new ParameterNode() { Name = pathName, ChildNodes = new ObservableCollection<ParameterNode>(), ParentNode = parentNode };
  96. if (parentNode == null)
  97. {
  98. rootNode.Add(indexer[pathName]);
  99. }
  100. else
  101. {
  102. parentNode.ChildNodes.Add(indexer[pathName]);
  103. }
  104. }
  105. parentNode = indexer[pathName];
  106. }
  107. }
  108. SortParameterNode(rootNode, "Heater", 0);
  109. SortParameterNode(rootNode, "MFC", 1);
  110. SortParameterNode(rootNode, "Pressure", 2);
  111. SortParameterNode(rootNode, "Boat", 3);
  112. SortParameterNode(rootNode, "HeaterBand", 4);
  113. SortParameterNode(rootNode, "Valve", 5);
  114. }
  115. }
  116. catch (Exception ex)
  117. {
  118. LOG.Write(ex);
  119. }
  120. return rootNode;
  121. }
  122. void SortParameterNode(ObservableCollection<ParameterNode> rootNode, string Name, int Index)
  123. {
  124. if (rootNode[Index].Name != Name)
  125. {
  126. for (int i = 0; i < rootNode.Count; i++)
  127. {
  128. rootNode[i].Selected = true;
  129. if (rootNode[i].Name == Name)
  130. {
  131. ParameterNode node = rootNode[i];
  132. rootNode.RemoveAt(i);
  133. rootNode.Insert(Index, node);
  134. }
  135. }
  136. }
  137. }
  138. private IRange _timeRange;
  139. public IRange VisibleRangeTime
  140. {
  141. get { return _timeRange; }
  142. set
  143. {
  144. _timeRange = value;
  145. NotifyOfPropertyChange(nameof(VisibleRangeTime));
  146. }
  147. }
  148. private IRange _VisibleRangeValue;
  149. public IRange VisibleRangeValue
  150. {
  151. get { return _VisibleRangeValue; }
  152. set { _VisibleRangeValue = value; NotifyOfPropertyChange(nameof(VisibleRangeValue)); }
  153. }
  154. private AnnotationCollection _annotations;
  155. public AnnotationCollection Annotations
  156. {
  157. get => _annotations;
  158. set
  159. {
  160. _annotations = value;
  161. InvokePropertyChanged(nameof(Annotations));
  162. }
  163. }
  164. //private PeriodicJob _thread;
  165. private List<StepInfo> _stepInfo = new List<StepInfo>();
  166. public List<StepInfo> StepInfo
  167. {
  168. get { return _stepInfo; }
  169. set { _stepInfo = value; this.NotifyOfPropertyChange(nameof(StepInfo)); }
  170. }
  171. private bool _isBusy = false;
  172. private string _busyIndicatorMessage;
  173. /// <summary>
  174. /// 设置或返回忙信息。
  175. /// </summary>
  176. public string BusyIndicatorContent
  177. {
  178. get => _busyIndicatorMessage;
  179. set
  180. {
  181. _busyIndicatorMessage = value;
  182. NotifyOfPropertyChange(nameof(BusyIndicatorContent));
  183. }
  184. }
  185. /// <summary>
  186. /// 设置或返回视图是否正忙。
  187. /// </summary>
  188. public bool IsBusy
  189. {
  190. get => _isBusy;
  191. set
  192. {
  193. _isBusy = value;
  194. NotifyOfPropertyChange(nameof(IsBusy));
  195. }
  196. }
  197. private RealtimeProvider _realtimeProvider;
  198. public ProcessExportAllViewModel(List<ProcessHistoryLot> recipes)
  199. {
  200. DisplayName = "Process Export";
  201. RecipeDatas = recipes;
  202. _realtimeProvider = new RealtimeProvider();
  203. ParameterNodes = _realtimeProvider.GetParameters(out var dict, true);
  204. _processDetailDisplayDic = dict;
  205. _processProcessDetailAttributeDict = _realtimeProvider.GetProcessProcessDetailAttributeDict();
  206. if (recipes == null || recipes.Count == 0)
  207. {
  208. return;
  209. }
  210. //SelectedData = new ObservableCollection<IRenderableSeries>();
  211. var now = DateTime.Now;
  212. VisibleRangeTime = new DateRange(DateTime.Now.AddMinutes(60), DateTime.Now.AddMinutes(-60));
  213. VisibleRangeValue = new DoubleRange(0, 10);
  214. Annotations = new AnnotationCollection();
  215. // _thread = new PeriodicJob(200, MonitorData, "ProcessExport", true);
  216. RecipeDatas.ToList().ForEach(recipe =>
  217. {
  218. QueryStep(recipe);
  219. });
  220. if (StepInfo != null && StepInfo.Count > 0)
  221. {
  222. StepStartTime = StepInfo.FirstOrDefault().StartTime;
  223. StepEndTime = StepInfo.LastOrDefault().EndTime;
  224. }
  225. else
  226. {
  227. if (recipes.Count > 0)
  228. {
  229. StepStartTime = recipes[0].StartTime;
  230. StepEndTime = recipes[0].EndTime;
  231. }
  232. }
  233. }
  234. public bool IsStepVisiable => RecipeDatas.Count == 1;
  235. public DateTime StepStartTime { get; set; }
  236. public DateTime StepEndTime { get; set; }
  237. private bool _isAdding;
  238. private static object _lockSelection = new object();
  239. private ConcurrentBag<QueryIndexer> _lstTokenTimeData = new ConcurrentBag<QueryIndexer>();
  240. public class QueryIndexer
  241. {
  242. public TimeChartDataLine DataLine { get; set; }
  243. public List<string> DataList { get; set; }
  244. public DateTime TimeToken { get; set; }
  245. }
  246. public class TimeChartDataLine : ChartDataLine<T>
  247. {
  248. public string Module { get; set; }
  249. public DateTime StartTime { get; set; }
  250. public DateTime EndTime { get; set; }
  251. public TimeChartDataLine(string dataName, string module, DateTime startTime, DateTime endTime) : base(dataName)
  252. {
  253. StartTime = startTime;
  254. EndTime = endTime;
  255. Module = module;
  256. }
  257. }
  258. private string _resolution;
  259. private AutoRange _autoRange;
  260. public AutoRange ChartAutoRange
  261. {
  262. get { return _autoRange; }
  263. set
  264. {
  265. _autoRange = value;
  266. NotifyOfPropertyChange(nameof(ChartAutoRange));
  267. }
  268. }
  269. public void QueryStep(ProcessHistoryLot historyLot)//, string recipeName去掉查询recipeName名称,有嵌套调用
  270. {
  271. string sql = string.Empty;
  272. DataTable dbData = new DataTable();
  273. if (!string.IsNullOrEmpty(historyLot.PjId))
  274. {
  275. sql = $"SELECT * FROM process_data where pj_id='{historyLot.PjId}'";
  276. dbData = QueryDataClient.Instance.Service.QueryData(sql);
  277. }
  278. if (dbData == null || dbData.Rows.Count == 0)
  279. {
  280. DateTime starTime = historyLot.StartTime.AddMinutes(-1);
  281. DateTime endTime = historyLot.EndTime.AddMinutes(1);
  282. sql = $"SELECT * FROM \"process_data\" where (\"process_begin_time\" >= '{starTime:yyyy/MM/dd HH:mm:ss.fff}' and \"process_end_time\" <= '{endTime:yyyy/MM/dd HH:mm:ss.fff}') order by \"process_begin_time\" DESC;";
  283. dbData = QueryDataClient.Instance.Service.QueryData(sql);
  284. }
  285. if (dbData != null && dbData.Rows.Count > 0)
  286. {
  287. List<ProcessDataLot> ProcessDataLotList = new List<ProcessDataLot>();
  288. for (int i = 0; i < dbData.Rows.Count; i++)
  289. {
  290. ProcessDataLot item = new ProcessDataLot();
  291. item.GUID = dbData.Rows[i]["guid"].ToString();
  292. item.RecipeName = dbData.Rows[i]["recipe_name"].ToString();
  293. item.ProcessStatus = dbData.Rows[i]["process_status"].ToString();
  294. item.WaferDataGUID = dbData.Rows[i]["wafer_data_guid"].ToString();
  295. item.ProcessIn = dbData.Rows[i]["process_in"].ToString();
  296. item.RecipeType = dbData.Rows[i]["recipe_type"].ToString();
  297. item.RecipeExeEntry = dbData.Rows[i]["recipe_exec_entry"].ToString();
  298. if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))
  299. {
  300. item.ProcessBeginTime = (DateTime)dbData.Rows[i]["process_begin_time"];
  301. }
  302. if (!dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))
  303. {
  304. item.ProcessEndTime = (DateTime)dbData.Rows[i]["process_end_time"];
  305. }
  306. ProcessDataLotList.Add(item);
  307. }
  308. if (ProcessDataLotList.Count == 0) { LOG.Warning($"QueryStep:No process data({sql})"); return; }
  309. historyLot.ProcessStartTime = ProcessDataLotList[0].ProcessBeginTime;
  310. historyLot.ProcessEndTime = ProcessDataLotList[0].ProcessEndTime;
  311. if (int.TryParse(ProcessDataLotList[0].RecipeType, out int type))
  312. historyLot.RecipeType = (RecipeTypeEnum)type;
  313. if (int.TryParse(ProcessDataLotList[0].RecipeExeEntry, out int entry))
  314. historyLot.RecipeExecEntry = (RecipeExecEntryEnum)entry;
  315. // Annotations.Add(VerLine(Media.Brushes.Blue, ProcessDataLotList[0].ProcessBeginTime, Media.Brushes.Blue, $"{ProcessDataLotList[0].RecipeName}"));
  316. //Annotations.Add(VerLine(Media.Brushes.Blue, ProcessDataLotList[0].ProcessEndTime, Media.Brushes.Blue, $"Recipe End"));
  317. string sql2 = $"SELECT * FROM \"recipe_step_data\" where";
  318. sql2 += $" \"recipe_step_data\".\"process_data_guid\" = '{ProcessDataLotList[0].GUID.ToString()}'";
  319. sql2 += " order by \"step_begin_time\" ASC;";
  320. using (var table = QueryDataClient.Instance.Service.QueryData(sql2))
  321. {
  322. if (!(table == null || table.Rows.Count == 0))
  323. {
  324. for (int i = 0; i < table.Rows.Count; i++)
  325. {
  326. var item = table.Rows[i];
  327. string startStepTime = "";
  328. string endStepTime = "";
  329. double stepTime = 0;
  330. string subRecipeStepNumber = "";
  331. string subRecipeStepTime = "";
  332. string subRecipeStepName = "";
  333. string subRecipeLoopInfo = "";
  334. string tempCorrection = "";
  335. string tempPid = "";
  336. if (!item["step_begin_time"].Equals(DBNull.Value))
  337. startStepTime = ((DateTime)item["step_begin_time"]).ToString("yyyy/MM/dd HH:mm:ss.fff");
  338. if (!item["step_end_time"].Equals(DBNull.Value))
  339. {
  340. endStepTime = ((DateTime)item["step_end_time"]).ToString("yyyy/MM/dd HH:mm:ss.fff");
  341. }
  342. if (!item["step_time"].Equals(DBNull.Value))
  343. {
  344. stepTime = (float)item["step_time"];
  345. }
  346. if (!item["sub_recipe_step_time"].Equals(DBNull.Value))
  347. {
  348. subRecipeStepTime = item["sub_recipe_step_time"].ToString();
  349. }
  350. if (!item["sub_recipe_step_number"].Equals(DBNull.Value))
  351. {
  352. subRecipeStepNumber = item["sub_recipe_step_number"].ToString();
  353. }
  354. if (!item["sub_recipe_step_name"].Equals(DBNull.Value))
  355. {
  356. subRecipeStepName = item["sub_recipe_step_name"].ToString();
  357. }
  358. if (!item["sub_recipe_loop_info"].Equals(DBNull.Value))
  359. {
  360. subRecipeLoopInfo = item["sub_recipe_loop_info"].ToString();
  361. }
  362. if (!item["temp_correction"].Equals(DBNull.Value))
  363. {
  364. tempCorrection = item["temp_correction"].ToString().Replace(",", ":");
  365. }
  366. if (!item["temp_pid"].Equals(DBNull.Value))
  367. {
  368. tempPid = item["temp_pid"].ToString().Replace(",", ":");
  369. }
  370. string stepNo = item["step_number"].ToString();
  371. string stepName = item["step_name"].ToString();
  372. if (DateTime.TryParse(startStepTime, out DateTime StartTime) && DateTime.TryParse(endStepTime, out DateTime EndTime))
  373. {
  374. //Annotations.Add(VerLine(Media.Brushes.AliceBlue, StartTime, Media.Brushes.Blue, $"{stepNo}"));
  375. var time = StartTime.AddSeconds(stepTime);
  376. if (EndTime < time && time < ProcessDataLotList[0].ProcessEndTime)//解决process过程abort,数据导出问题:数据点时间范围大于recipe结束时间。
  377. {
  378. EndTime = StartTime.AddSeconds(stepTime);
  379. }
  380. _stepInfo.Add(new StepInfo()
  381. {
  382. StartTime = StartTime,
  383. EndTime = EndTime,
  384. StepName = stepName,
  385. StepTime = stepTime,
  386. StepNo = stepNo,
  387. StepEndTime = StartTime.AddSeconds(stepTime),
  388. SubRecipeStepNumber = subRecipeStepNumber,
  389. SubRecipeStepTime = subRecipeStepTime,
  390. SubRecipeStepName = subRecipeStepName,
  391. SubRecipeLoopInfo = subRecipeLoopInfo,
  392. TempCorrection = tempCorrection,
  393. TempPid = tempPid,
  394. });
  395. }
  396. }
  397. }
  398. }
  399. }
  400. }
  401. protected override void OnViewLoaded(object view)
  402. {
  403. base.OnViewLoaded(view);
  404. useMaxRow = (int)QueryDataClient.Instance.Service.GetConfig("System.SetUp.ExportMaxRow");
  405. this.view = (ProcessExportAllView)view;
  406. }
  407. List<string> nodeOrigin = new List<string>();
  408. void GetNode(ParameterNode pNode, bool Selected)
  409. {
  410. foreach (var item in pNode.ChildNodes)
  411. {
  412. if (item.ChildNodes.Count > 0)
  413. {
  414. GetNode(item, Selected);
  415. }
  416. else
  417. {
  418. //if(item.Selected == true)
  419. {
  420. nodeOrigin.Add(item.Name);
  421. }
  422. }
  423. }
  424. }
  425. public static int DivideAndRoundUp(int dividend, int divisor)
  426. {
  427. int result = dividend / divisor;
  428. int remainder = dividend % divisor;
  429. if (remainder > 0)
  430. {
  431. result++;
  432. }
  433. return result;
  434. }
  435. private int useMaxRow = 25000;
  436. string csv = ",";
  437. public async void ExportAll()
  438. {
  439. try
  440. {
  441. nodeOrigin.Clear();
  442. if (StepStartTime.Year == 1 || StepEndTime.Year == 1)
  443. {
  444. MessageBox.Show("No data is available in the selected period!", "Export", MessageBoxButton.OK, MessageBoxImage.Warning);
  445. return;
  446. }
  447. foreach (var node in ParameterNodes)
  448. {
  449. if (node.Selected == true)
  450. {
  451. GetNode(node, node.Selected);
  452. }
  453. }
  454. if (nodeOrigin.Count == 0)
  455. {
  456. MessageBox.Show($"Please select the data you want to export.", "Export", MessageBoxButton.OK,
  457. MessageBoxImage.Warning);
  458. return;
  459. }
  460. Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
  461. dlg.DefaultExt = ".csv"; // Default file extension
  462. dlg.Filter = "Excel数据表格文件(*.csv)|*.csv"; // Filter files by extension
  463. //去除创建文件时的文件名中包含的非法字符'\'
  464. dlg.FileName = $"{DisplayName}_{string.Join(",", RecipeDatas.Select(x => x.RecipeName.Replace('\\', '.')))}_{DateTime.Now:yyyyMMdd_HHmmss}";
  465. Nullable<bool> result = dlg.ShowDialog();// Show open file dialog box
  466. if (result == true) // Process open file dialog box results
  467. {
  468. BusyIndicatorContent = "Exporting start ...";
  469. IsBusy = true;
  470. Exporting?.Invoke(this, System.EventArgs.Empty);
  471. _cancellationTokenSource = new CancellationTokenSource();
  472. await Task.Run(() =>
  473. {
  474. DateTime startTime = startTime = StepStartTime;
  475. QueryDataClientFromTable(dlg.FileName, RecipeDatas.FirstOrDefault());
  476. }, _cancellationTokenSource.Token).ContinueWith(t =>
  477. {
  478. if (t.IsCanceled || t.IsFaulted)
  479. {
  480. IsBusy = false;
  481. return;
  482. }
  483. });
  484. if (_cancellationTokenSource?.Token.IsCancellationRequested == true)
  485. {
  486. IsBusy = false;
  487. return;
  488. }
  489. BusyIndicatorContent = "Data is written to Excel file ...";
  490. IsBusy = false;
  491. MessageBox.Show($"Export succeed, file save as {dlg.FileName}", "Export", MessageBoxButton.OK, MessageBoxImage.Information);
  492. Window window = Window.GetWindow(this.view);
  493. window.Close();
  494. }
  495. }
  496. catch (Exception ex)
  497. {
  498. LOG.Write(ex);
  499. MessageBox.Show("Write failed," + ex.Message, "export failed", MessageBoxButton.OK, MessageBoxImage.Warning);
  500. IsBusy = false;
  501. }
  502. }
  503. private void QueryDataClientFromTable(string fileName, ProcessHistoryLot recipeInfo)
  504. {
  505. DateTime startTime = StepStartTime;
  506. DateTime endTime = StepEndTime;
  507. List<string> keys = new List<string>(nodeOrigin);
  508. List<string> pmList = new List<string>();
  509. List<string> systemList = new List<string>();
  510. if (keys != null && keys.Count > 0)
  511. {
  512. keys = _processDetailDisplayDic.Keys.Intersect(keys).OrderBy(key => _processDetailDisplayDic.Keys.ToList().IndexOf(key)).ToList();
  513. foreach (var dataKey in keys)
  514. {
  515. var dataId = _processDetailDisplayDic.ContainsKey(dataKey) ? _processDetailDisplayDic[dataKey] : dataKey;
  516. var module = dataId.Split('.').ToList()[0];
  517. if (module.ToLower() == "pm1")
  518. {
  519. pmList.Add(dataId);
  520. }
  521. else if (module.ToLower() == "system")
  522. {
  523. systemList.Add(dataId);
  524. // systemList.Add(string.Format("\"{0}\"", dataId));
  525. }
  526. }
  527. }
  528. List<DataTable> pmTableList = new List<DataTable>();
  529. List<DataTable> systemTableList = new List<DataTable>();
  530. if (StepStartTime.Date == StepEndTime.Date)
  531. {
  532. var pmItem = GetDataTable(ModuleName.PM1, pmList, startTime, endTime);
  533. pmTableList.Add(pmItem);
  534. var systemmItem = GetDataTable(ModuleName.System, systemList, startTime, endTime);
  535. systemTableList.Add(systemmItem);
  536. }
  537. else
  538. {
  539. endTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 23, 59, 59);
  540. while (endTime < StepEndTime)
  541. {
  542. var pmItemWhile = GetDataTable(ModuleName.PM1, pmList, startTime, endTime);
  543. pmTableList.Add(pmItemWhile);
  544. var systemmItemWhile = GetDataTable(ModuleName.System, systemList, startTime, endTime);
  545. systemTableList.Add(systemmItemWhile);
  546. startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 0, 0, 0).AddDays(1);
  547. endTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 23, 59, 59);
  548. }
  549. var pmItem = GetDataTable(ModuleName.PM1, pmList, startTime, StepEndTime);
  550. pmTableList.Add(pmItem);
  551. var systemmItem = GetDataTable(ModuleName.System, systemList, startTime, StepEndTime);
  552. systemTableList.Add(systemmItem);
  553. }
  554. pmTableList = pmTableList.Where(a => a != null).ToList();
  555. systemTableList = systemTableList.Where(a => a != null).ToList();
  556. DataTable pm = new DataTable();
  557. DataTable system = new DataTable();
  558. if (pmTableList != null && pmTableList.Count > 0)
  559. pm = MergeDataTables(pmTableList, pmTableList.FirstOrDefault().Columns.Cast<DataColumn>().Select(c => c.ColumnName).ToList());
  560. if (systemTableList != null && systemTableList.Count > 0)
  561. system = MergeDataTables(systemTableList, systemTableList.FirstOrDefault().Columns.Cast<DataColumn>().Select(c => c.ColumnName).ToList());
  562. SaveDataToTable(pm, system, fileName, pmList, systemList, startTime, endTime, recipeInfo);
  563. }
  564. private bool firstHeader = false;
  565. private Dictionary<string, string> GetReverseDict()
  566. {
  567. Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
  568. foreach (var kvp in _processDetailDisplayDic)
  569. {
  570. if (!keyValuePairs.ContainsKey(kvp.Value))
  571. keyValuePairs[kvp.Value] = kvp.Key.Trim().Contains(" ") ? kvp.Key.Trim().Substring(kvp.Key.Trim().LastIndexOf(" ") + 1) : kvp.Key;
  572. }
  573. return keyValuePairs;
  574. }
  575. public class NeedCellColor
  576. {
  577. /// <summary>
  578. /// 是否需要单元格颜色
  579. /// </summary>
  580. public bool IsNeed;
  581. /// <summary>
  582. /// 配置项中的Color 数据,只支持16进制
  583. /// </summary>
  584. public string Color;
  585. }
  586. private static System.Drawing.Color ParseHexColor(string hexColor)
  587. {
  588. // 移除 #
  589. hexColor = hexColor.Replace("#", "").Trim();
  590. if (!ColorUtil.IsValidHexColor(hexColor))
  591. return System.Drawing.Color.Transparent;
  592. try
  593. {
  594. byte r = Convert.ToByte(hexColor.Substring(0, 2), 16);
  595. byte g = Convert.ToByte(hexColor.Substring(2, 2), 16);
  596. byte b = Convert.ToByte(hexColor.Substring(4, 2), 16);
  597. return System.Drawing.Color.FromArgb(r, g, b);
  598. }
  599. catch (Exception ex)
  600. {
  601. return System.Drawing.Color.Transparent;
  602. }
  603. }
  604. private void SaveDataToTable(DataTable pmDataTable, DataTable systemDataTable, string fileName, List<string> pmList, List<string> systemList, DateTime startTime, DateTime endTime, ProcessHistoryLot recipeInfo)
  605. {
  606. int numData = 35;
  607. var time = DateTime.Now;
  608. string stepID = "", stepName = "", subRecipeLoopInfo = "", subRecipeStepName = "", subRecipeStepNumber = "", tempCorrection = "", tempPid = "";
  609. Dictionary<DateTime, List<string>> pmDataDictList = new Dictionary<DateTime, List<string>>();
  610. if (pmDataTable != null && pmDataTable.Rows.Count > 0)
  611. {
  612. for (int i = 0; i < pmDataTable.Rows.Count; i++)
  613. {
  614. _cancellationTokenSource?.Token.ThrowIfCancellationRequested();
  615. List<string> strings = new List<string>();
  616. foreach (var item in pmList)
  617. {
  618. if (!pmDataTable.Columns.Contains(item))
  619. continue;
  620. strings.Add(pmDataTable.Rows[i][item].ToString());
  621. }
  622. pmDataDictList.Add(new DateTime((long)pmDataTable.Rows[i]["InternalTimeStamp"]), strings);
  623. }
  624. }
  625. Dictionary<DateTime, List<string>> systemDataDictList = new Dictionary<DateTime, List<string>>();
  626. if (systemDataTable != null && systemDataTable.Rows.Count > 0)
  627. {
  628. for (int i = 0; i < systemDataTable.Rows.Count; i++)
  629. {
  630. _cancellationTokenSource?.Token.ThrowIfCancellationRequested();
  631. List<string> strings = new List<string>();
  632. foreach (var item in systemList)
  633. {
  634. if (!systemDataTable.Columns.Contains(item))
  635. continue;
  636. strings.Add(systemDataTable.Rows[i][item].ToString());
  637. }
  638. systemDataDictList.Add(new DateTime((long)systemDataTable.Rows[i]["InternalTimeStamp"]), strings);
  639. }
  640. }
  641. IWorkbook workbook = new XSSFWorkbook();
  642. ISheet sheet = workbook.CreateSheet("Sheet1");
  643. #region Recipe 信息
  644. int rowIndex = 0;
  645. int cellIndex = 0;
  646. Dictionary<string, string> keyValuePairs = new Dictionary<string, string>()
  647. {
  648. { "Recipe Info",recipeInfo.RecipeName},
  649. { "Recipe StartTime",recipeInfo.ProcessStartTime.ToString(DateTimeUtil.DateTimeFormat)},
  650. { "Recipe EndTime",recipeInfo.ProcessEndTime.ToString(DateTimeUtil.DateTimeFormat)},
  651. { "Recipe Type",recipeInfo.RecipeType.ToString()},
  652. { "Recipe ExecEntry",recipeInfo.RecipeExecEntry.ToString()},
  653. };
  654. IRow dictRow = sheet.CreateRow(0);
  655. IRow dictRowTwo = sheet.CreateRow(1);
  656. dictRow.HeightInPoints = numData;
  657. dictRowTwo.HeightInPoints = numData;
  658. foreach (var kvp in keyValuePairs)
  659. {
  660. var RecipeCellIndex = cellIndex++;
  661. WriterCell(dictRow, RecipeCellIndex, workbook, kvp.Key, GetICellStyle(workbook));
  662. WriterCell(dictRowTwo, RecipeCellIndex, workbook, kvp.Value, GetICellStyle(workbook));
  663. }
  664. #endregion
  665. #region 数据列表头信息
  666. rowIndex = 4;
  667. cellIndex = 0;
  668. if (!firstHeader)
  669. {
  670. Dictionary<string, string> subColNames = new Dictionary<string, string>()
  671. {
  672. { "Step\nStartDate",ColorUtil.Color_Defalult},
  673. { "Step\nStartTime",ColorUtil.Color_Defalult},
  674. { "\tStepID\t ",ColorUtil.Color_Defalult},
  675. { "\tStepName\t",ColorUtil.Color_Defalult},
  676. { "SubRecipe\nStepName",ColorUtil.Color_Defalult},
  677. { "SubRecipe\nStepNumber",ColorUtil.Color_Defalult},
  678. { "SubRecipe\nLoopInfo",ColorUtil.Color_Defalult},
  679. { "Temp\nCorrection",ColorUtil.Color_Yellow},
  680. { "\tTempPID\t",ColorUtil.Color_Yellow},
  681. };
  682. firstHeader = true;
  683. var colColorNameDict = GetColNameColor(pmDataTable, systemDataTable);
  684. var pmColorDict = colColorNameDict.Item1;
  685. var systemmColorDict = colColorNameDict.Item2;
  686. IRow headerRow = sheet.CreateRow(rowIndex++);
  687. cellIndex = 0;
  688. headerRow.HeightInPoints = numData;
  689. foreach (var item in subColNames)
  690. {
  691. var dataCellIndex = cellIndex++;
  692. var needCellColor = new NeedCellColor() { IsNeed = false };
  693. if (subColNames.TryGetValue(item.Key, out var dataColor) && ColorUtil.IsValidHexColor(dataColor))
  694. {
  695. needCellColor.IsNeed = true;
  696. needCellColor.Color = dataColor;
  697. }
  698. WriterCell(headerRow, dataCellIndex, workbook, item.Key.Replace("(", "\n("), GetICellStyle(workbook, needCellColor));
  699. sheet.SetColumnWidth(dataCellIndex, 22 * 256);
  700. }
  701. foreach (var item in systemmColorDict.Keys)
  702. {
  703. var dataCellIndex = cellIndex++;
  704. var needCellColor = new NeedCellColor() { IsNeed = false };
  705. if (systemmColorDict.TryGetValue(item, out var dataColor) && ColorUtil.IsValidHexColor(dataColor))
  706. {
  707. needCellColor.IsNeed = true;
  708. needCellColor.Color = dataColor;
  709. }
  710. WriterCell(headerRow, dataCellIndex, workbook, item.Replace("(", "\n("), GetICellStyle(workbook, needCellColor));
  711. sheet.SetColumnWidth(dataCellIndex, item.Length * 256);
  712. }
  713. foreach (var item in pmColorDict.Keys)
  714. {
  715. var dataCellIndex = cellIndex++;
  716. var needCellColor = new NeedCellColor() { IsNeed = false };
  717. if (pmColorDict.TryGetValue(item, out var dataColor) && ColorUtil.IsValidHexColor(dataColor))
  718. {
  719. needCellColor.IsNeed = true;
  720. needCellColor.Color = dataColor;
  721. }
  722. WriterCell(headerRow, dataCellIndex, workbook, item.Replace("(", "\n("), GetICellStyle(workbook));
  723. sheet.SetColumnWidth(dataCellIndex, item.Length * 256);
  724. }
  725. }
  726. #endregion
  727. #region 数据列 行数据信息
  728. rowIndex = 5;
  729. _stepInfo = _stepInfo.OrderBy(x => x.StartTime).ToList();
  730. for (int i = 0; i < _stepInfo.Count; i++)
  731. {
  732. var tempStepInfo = _stepInfo[i];
  733. var rowCount = tempStepInfo.StepTime;
  734. if (!string.IsNullOrEmpty(tempStepInfo.SubRecipeStepNumber))
  735. {
  736. rowCount = int.Parse(tempStepInfo.SubRecipeStepTime);
  737. }
  738. for (int jx = 1; jx < rowCount + 1; jx++)
  739. {
  740. IRow dataRow = sheet.CreateRow(rowIndex++);
  741. dataRow.HeightInPoints = 25;
  742. var rowStartTime = jx == 1 ? tempStepInfo.StartTime : tempStepInfo.StartTime.AddSeconds(jx - 1);
  743. var rowEndTime = tempStepInfo.StartTime.AddSeconds(jx);
  744. if (tempStepInfo != null)
  745. {
  746. stepID = tempStepInfo.StepNo;
  747. stepName = tempStepInfo.StepName;
  748. subRecipeStepName = tempStepInfo.SubRecipeStepName;
  749. subRecipeStepNumber = tempStepInfo.SubRecipeStepNumber;
  750. subRecipeLoopInfo = !string.IsNullOrEmpty(tempStepInfo.SubRecipeLoopInfo) ? tempStepInfo.SubRecipeLoopInfo.Replace("/", "|") : tempStepInfo.SubRecipeLoopInfo;
  751. tempCorrection = !string.IsNullOrEmpty(tempStepInfo.TempCorrection) ? tempStepInfo.TempCorrection : "";
  752. tempPid = !string.IsNullOrEmpty(tempStepInfo.TempPid) ? tempStepInfo.TempPid : "";
  753. }
  754. cellIndex = 0;
  755. var pmRow = new List<string>();
  756. var newRowStartTime = new DateTime(rowStartTime.Year, rowStartTime.Month, rowStartTime.Day, rowStartTime.Hour, rowStartTime.Minute, rowStartTime.Second);
  757. var newRowEndTime = new DateTime(rowEndTime.Year, rowEndTime.Month, rowEndTime.Day, rowEndTime.Hour, rowEndTime.Minute, rowEndTime.Second);
  758. var rowPm = pmDataDictList.Keys.FirstOrDefault(a => a.Ticks >= newRowStartTime.Ticks);
  759. if (rowPm != null)
  760. pmRow = pmDataDictList[rowPm];
  761. var systemRow = new List<string>();
  762. var rowsSystem = systemDataDictList.Keys.FirstOrDefault(a => a.Ticks >= newRowStartTime.Ticks);
  763. if (rowsSystem != null)
  764. systemRow = systemDataDictList[rowsSystem];
  765. dataRow.CreateCell(cellIndex++).SetCellValue(rowStartTime.ToString(DateTimeUtil.DateFormat));
  766. dataRow.CreateCell(cellIndex++).SetCellValue(rowStartTime.ToString(DateTimeUtil.TimeFormat));
  767. dataRow.CreateCell(cellIndex++).SetCellValue(stepID);
  768. dataRow.CreateCell(cellIndex++).SetCellValue(stepName);
  769. dataRow.CreateCell(cellIndex++).SetCellValue(subRecipeStepName);
  770. dataRow.CreateCell(cellIndex++).SetCellValue(subRecipeStepNumber);
  771. dataRow.CreateCell(cellIndex++).SetCellValue(subRecipeLoopInfo);
  772. dataRow.CreateCell(cellIndex++).SetCellValue(tempCorrection);
  773. dataRow.CreateCell(cellIndex++).SetCellValue(tempPid);
  774. if (pmRow == null && systemRow != null)
  775. {
  776. for (int j = 1; j < systemRow.Count; j++)
  777. {
  778. WriterCell(dataRow, cellIndex++, workbook, systemRow[j].ToString());
  779. }
  780. for (int j = 0; j < (pmDataTable?.Columns.Count ?? 0); j++)
  781. {
  782. WriterCell(dataRow, cellIndex++, workbook, "");
  783. }
  784. }
  785. else if (pmRow != null && systemRow == null)
  786. {
  787. for (int j = 0; j < (systemDataTable?.Columns?.Count ?? 0); j++)
  788. {
  789. WriterCell(dataRow, cellIndex++, workbook, "");
  790. }
  791. for (int j = 1; j < pmRow.Count; j++)
  792. {
  793. WriterCell(dataRow, cellIndex++, workbook, ConvertBooleanValues(pmRow[j]));
  794. }
  795. }
  796. else if (systemDataTable != null)
  797. {
  798. for (int j = 1; j < systemRow.Count; j++)
  799. {
  800. WriterCell(dataRow, cellIndex++, workbook, systemRow[j].ToString());
  801. }
  802. for (int j = 1; j < pmRow.Count; j++)
  803. {
  804. WriterCell(dataRow, cellIndex++, workbook, ConvertBooleanValues(pmRow[j]));
  805. }
  806. }
  807. }
  808. }
  809. #endregion
  810. sheet.CreateFreezePane(4, 5);
  811. using (MemoryStream memoryStream = new MemoryStream())
  812. {
  813. workbook.Write(memoryStream);
  814. File.WriteAllBytes(fileName, memoryStream.ToArray());
  815. }
  816. }
  817. #region 抽离方法
  818. private ICellStyle GetICellStyle(IWorkbook workbook, NeedCellColor needCellColor = null)
  819. {
  820. ICellStyle cellStyle = workbook.CreateCellStyle();
  821. cellStyle.WrapText = true;
  822. cellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
  823. cellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
  824. cellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
  825. cellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
  826. cellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
  827. cellStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
  828. if (needCellColor != null && needCellColor.IsNeed)
  829. {
  830. string hexColor = needCellColor.Color;
  831. XSSFColor colorIndex = new XSSFColor(ParseHexColor(hexColor));
  832. ((XSSFCellStyle)cellStyle).SetFillForegroundColor(colorIndex);
  833. cellStyle.FillPattern = FillPattern.SolidForeground;
  834. }
  835. return cellStyle;
  836. }
  837. private string ConvertBooleanValues(object value)
  838. {
  839. if (bool.TryParse(value.ToString(), out bool avData))
  840. {
  841. return avData ? "Open" : "Close";
  842. }
  843. return value.ToString();
  844. }
  845. private DataTable MergeDataTables(List<DataTable> tables, List<string> commonColumns)
  846. {
  847. if (!tables.Any()) return new DataTable();
  848. DataTable result = new DataTable();
  849. // 添加列(确保顺序一致)
  850. foreach (var colName in commonColumns)
  851. {
  852. var sampleCol = tables[0].Columns[colName];
  853. result.Columns.Add(colName, sampleCol.DataType);
  854. }
  855. // 合并每一行
  856. foreach (var table in tables)
  857. {
  858. foreach (DataRow row in table.Rows)
  859. {
  860. var newRow = result.NewRow();
  861. foreach (var colName in commonColumns)
  862. {
  863. if (row[colName] != DBNull.Value)
  864. newRow[colName] = row[colName];
  865. else
  866. newRow[colName] = DBNull.Value;
  867. }
  868. result.Rows.Add(newRow);
  869. }
  870. }
  871. // 排序最终结果(按时间戳)
  872. DataView view = result.DefaultView;
  873. view.Sort = "InternalTimeStamp ASC";
  874. return view.ToTable();
  875. }
  876. public DataTable GetDataTable(ModuleName type, List<string> queryColNameList, DateTime startTime, DateTime endTime)
  877. {
  878. startTime = startTime.AddSeconds(-10);
  879. endTime = endTime.AddSeconds(10);
  880. var tableName = ModuleName.PM1.ToString();
  881. if (type == ModuleName.System)
  882. tableName = ModuleName.System.ToString();
  883. DataTable resultTable = null;
  884. var columnsql = $"select column_name from information_schema.columns where table_name = '{startTime.ToString("yyyyMMdd")}.{tableName}'";
  885. var columnTable = QueryDataClient.Instance.Service.QueryData(columnsql);
  886. List<string> col = columnTable.Rows.Cast<DataRow>().Select(x => x.ItemArray[0].ToString()).ToList();
  887. queryColNameList = queryColNameList.Where(x => col.Any(y => y == x)).ToList();
  888. var tableColName = queryColNameList.Select(x => string.Format("\"{0}\"", x));
  889. string pmsql = $"select time AS InternalTimeStamp, {string.Join(",", tableColName)}";
  890. pmsql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc",
  891. startTime.ToString("yyyyMMdd") + "." + $"{tableName}", startTime.Ticks, endTime.Ticks);
  892. BusyIndicatorContent = $"Example Query {tableName} data ...";
  893. resultTable = QueryDataClient.Instance.Service.QueryData(pmsql);
  894. return resultTable;
  895. }
  896. private int GetMaxRow(DataTable pmDataTable, DataTable systemDataTable)
  897. {
  898. int maxRow = 0;
  899. if ((pmDataTable == null || pmDataTable.Rows.Count == 0))
  900. {
  901. if (systemDataTable != null)
  902. {
  903. maxRow = systemDataTable.Rows.Count;
  904. }
  905. }
  906. else if ((systemDataTable == null || systemDataTable.Rows.Count == 0))
  907. {
  908. if (pmDataTable != null)
  909. {
  910. maxRow = pmDataTable.Rows.Count;
  911. }
  912. }
  913. else
  914. {
  915. maxRow = pmDataTable.Rows.Count > systemDataTable.Rows.Count ? systemDataTable.Rows.Count : pmDataTable.Rows.Count;
  916. }
  917. return maxRow;
  918. }
  919. private Tuple<Dictionary<string, string>, Dictionary<string, string>> GetColNameColor(DataTable pmDataTable, DataTable systemDataTable)
  920. {
  921. Dictionary<string, string> systemColorNameDict = new Dictionary<string, string>();
  922. foreach (var item in systemDataTable?.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp"))
  923. {
  924. if (!_processProcessDetailAttributeDict.ContainsKey(item.ColumnName))
  925. {
  926. systemColorNameDict.Add(item.ColumnName, "");
  927. continue;
  928. }
  929. var colAttributeName = "ColName";
  930. if (!_processProcessDetailAttributeDict[item.ColumnName].ContainsKey(colAttributeName))
  931. {
  932. colAttributeName = "DisplayName";
  933. }
  934. var tempStr = _processProcessDetailAttributeDict[item.ColumnName].ContainsKey("DisplayName") && !string.IsNullOrEmpty(_processProcessDetailAttributeDict[item.ColumnName]["DisplayName"]) ? _processProcessDetailAttributeDict[item.ColumnName]["DisplayName"] : item.ColumnName;
  935. var resultName = string.IsNullOrEmpty(_processProcessDetailAttributeDict[item.ColumnName][colAttributeName]) ? item.ColumnName : _processProcessDetailAttributeDict[item.ColumnName][colAttributeName];
  936. colAttributeName = "Color";
  937. var resultColor = "";
  938. if (_processProcessDetailAttributeDict[item.ColumnName].ContainsKey(colAttributeName))
  939. resultColor = string.IsNullOrEmpty(_processProcessDetailAttributeDict[item.ColumnName][colAttributeName]) ? "" : _processProcessDetailAttributeDict[item.ColumnName][colAttributeName];
  940. systemColorNameDict.Add(resultName, resultColor);
  941. }
  942. Dictionary<string, string> pmColorNameDict = new Dictionary<string, string>();
  943. foreach (var item in pmDataTable?.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp"))
  944. {
  945. if (!_processProcessDetailAttributeDict.ContainsKey(item.ColumnName))
  946. {
  947. pmColorNameDict.Add(item.ColumnName, "");
  948. continue;
  949. }
  950. var colAttributeName = "ColName";
  951. if (!_processProcessDetailAttributeDict[item.ColumnName].ContainsKey(colAttributeName))
  952. {
  953. colAttributeName = "DisplayName";
  954. }
  955. var tempStr = _processProcessDetailAttributeDict[item.ColumnName].ContainsKey("DisplayName") && !string.IsNullOrEmpty(_processProcessDetailAttributeDict[item.ColumnName]["DisplayName"]) ? _processProcessDetailAttributeDict[item.ColumnName]["DisplayName"] : item.ColumnName;
  956. var resultName = string.IsNullOrEmpty(_processProcessDetailAttributeDict[item.ColumnName][colAttributeName]) ? item.ColumnName : _processProcessDetailAttributeDict[item.ColumnName][colAttributeName];
  957. colAttributeName = "Color";
  958. var resultColor = "";
  959. if (_processProcessDetailAttributeDict[item.ColumnName].ContainsKey(colAttributeName))
  960. resultColor = string.IsNullOrEmpty(_processProcessDetailAttributeDict[item.ColumnName][colAttributeName]) ? "" : _processProcessDetailAttributeDict[item.ColumnName][colAttributeName];
  961. pmColorNameDict.Add(resultName, resultColor);
  962. }
  963. return new Tuple<Dictionary<string, string>, Dictionary<string, string>>(pmColorNameDict, systemColorNameDict);
  964. }
  965. private Tuple<IEnumerable<string>, IEnumerable<string>> GetColName(DataTable pmDataTable, DataTable systemDataTable)
  966. {
  967. var systemColNames = systemDataTable?.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp").Select(x =>
  968. {
  969. if (_processProcessDetailAttributeDict.ContainsKey(x.ColumnName))
  970. {
  971. var colAttributeName = "ColName";
  972. if (!_processProcessDetailAttributeDict[x.ColumnName].ContainsKey(colAttributeName))
  973. {
  974. colAttributeName = "DisplayName";
  975. }
  976. var tempStr = _processProcessDetailAttributeDict[x.ColumnName].ContainsKey("DisplayName") && !string.IsNullOrEmpty(_processProcessDetailAttributeDict[x.ColumnName]["DisplayName"]) ? _processProcessDetailAttributeDict[x.ColumnName]["DisplayName"] : x.ColumnName;
  977. return string.IsNullOrEmpty(_processProcessDetailAttributeDict[x.ColumnName][colAttributeName]) ? x.ColumnName : _processProcessDetailAttributeDict[x.ColumnName][colAttributeName];
  978. }
  979. return x.ColumnName;
  980. });
  981. var pmColNames = pmDataTable?.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp").Select(x =>
  982. {
  983. if (_processProcessDetailAttributeDict.ContainsKey(x.ColumnName))
  984. {
  985. var colAttributeName = "ColName";
  986. if (!_processProcessDetailAttributeDict[x.ColumnName].ContainsKey(colAttributeName))
  987. {
  988. colAttributeName = "DisplayName";
  989. }
  990. var tempStr = _processProcessDetailAttributeDict[x.ColumnName].ContainsKey("DisplayName") && !string.IsNullOrEmpty(_processProcessDetailAttributeDict[x.ColumnName]["DisplayName"]) ? _processProcessDetailAttributeDict[x.ColumnName]["DisplayName"] : x.ColumnName;
  991. return string.IsNullOrEmpty(_processProcessDetailAttributeDict[x.ColumnName][colAttributeName]) ? x.ColumnName : _processProcessDetailAttributeDict[x.ColumnName][colAttributeName];
  992. }
  993. return x.ColumnName;
  994. });
  995. return new Tuple<IEnumerable<string>, IEnumerable<string>>(pmColNames, systemColNames);
  996. }
  997. private void WriterCell(IRow row, int cellIndex, IWorkbook workbook, string setValue, ICellStyle cellStyle = null)
  998. {
  999. ICell keyCell = row.CreateCell(cellIndex);
  1000. keyCell.SetCellValue(setValue);
  1001. keyCell.CellStyle = cellStyle;
  1002. }
  1003. #endregion
  1004. static string CheckAndReplace(string input)
  1005. {
  1006. if (input.StartsWith("PM1"))
  1007. {
  1008. return input.Substring(4);
  1009. }
  1010. if (input.StartsWith("System"))
  1011. {
  1012. return input.Substring(7);
  1013. }
  1014. return input;
  1015. }
  1016. /// <summary>
  1017. /// 取消查询。
  1018. /// </summary>
  1019. public void CancelQuery()
  1020. {
  1021. Task.Run(() =>
  1022. {
  1023. if (_cancellationTokenSource?.Token.CanBeCanceled == true)
  1024. {
  1025. _cancellationTokenSource.Cancel();
  1026. }
  1027. Thread.Sleep(100);
  1028. //_progQueryUpdate.Report(new ProgressUpdatingEventArgs(100, 100, ""));
  1029. //_progChartSuspendUpdating.Report(false);
  1030. });
  1031. }
  1032. }
  1033. }