ProcessExportAllViewModel.cs 50 KB

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