ProcessExportAllViewModel.cs 53 KB

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