|
@@ -1,21 +1,19 @@
|
|
|
-using Aitex.Core.RT.Log;
|
|
|
-using Aitex.Core.UI.ControlDataContext;
|
|
|
-using Aitex.Core.Util;
|
|
|
-using Caliburn.Micro;
|
|
|
-using Caliburn.Micro.Core;
|
|
|
+using Aitex.Core.Backend;
|
|
|
+using Aitex.Core.RT.IOCore;
|
|
|
+using Aitex.Core.RT.Log;
|
|
|
+using DocumentFormat.OpenXml.Packaging;
|
|
|
using DocumentFormat.OpenXml.Spreadsheet;
|
|
|
-using MECF.Framework.Common.CommonData;
|
|
|
using MECF.Framework.Common.CommonData.EnumData;
|
|
|
using MECF.Framework.Common.ControlDataContext;
|
|
|
using MECF.Framework.Common.DataCenter;
|
|
|
+using MECF.Framework.Common.Equipment;
|
|
|
using MECF.Framework.Common.Utilities;
|
|
|
using MECF.Framework.UI.Client.CenterViews.Configs.SystemConfig;
|
|
|
using MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory;
|
|
|
using MECF.Framework.UI.Client.CenterViews.Dialogs;
|
|
|
using MECF.Framework.UI.Client.CenterViews.Operations.RealTime;
|
|
|
using MECF.Framework.UI.Client.ClientBase;
|
|
|
-using NPOI.HSSF.UserModel;
|
|
|
-using NPOI.HSSF.Util;
|
|
|
+
|
|
|
using NPOI.SS.UserModel;
|
|
|
using NPOI.XSSF.UserModel;
|
|
|
using OpenSEMI.ClientBase;
|
|
@@ -595,23 +593,49 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+ List<DataTable> pmTableList = new List<DataTable>();
|
|
|
+ List<DataTable> systemTableList = new List<DataTable>();
|
|
|
if (StepStartTime.Date == StepEndTime.Date)
|
|
|
{
|
|
|
+ var pmItem = GetDataTable(ModuleName.PM1, pmList, startTime, endTime);
|
|
|
+ pmTableList.Add(pmItem);
|
|
|
|
|
|
- SaveDataToTable(fileName, pmList, systemList, startTime, endTime, recipeInfo);
|
|
|
+ var systemmItem = GetDataTable(ModuleName.System, systemList, startTime, endTime);
|
|
|
+ systemTableList.Add(systemmItem);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
endTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 23, 59, 59);
|
|
|
while (endTime < StepEndTime)
|
|
|
{
|
|
|
- SaveDataToTable(fileName, pmList, systemList, startTime, endTime, recipeInfo);
|
|
|
+ var pmItemWhile = GetDataTable(ModuleName.PM1, pmList, startTime, endTime);
|
|
|
+ pmTableList.Add(pmItemWhile);
|
|
|
+
|
|
|
+ var systemmItemWhile = GetDataTable(ModuleName.System, systemList, startTime, endTime);
|
|
|
+ systemTableList.Add(systemmItemWhile);
|
|
|
+
|
|
|
startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 0, 0, 0).AddDays(1);
|
|
|
endTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 23, 59, 59);
|
|
|
}
|
|
|
- SaveDataToTable(fileName, pmList, systemList, startTime, StepEndTime, recipeInfo);
|
|
|
+ var pmItem = GetDataTable(ModuleName.PM1, pmList, startTime, StepEndTime);
|
|
|
+ pmTableList.Add(pmItem);
|
|
|
+
|
|
|
+ var systemmItem = GetDataTable(ModuleName.System, systemList, startTime, StepEndTime);
|
|
|
+ systemTableList.Add(systemmItem);
|
|
|
}
|
|
|
+ pmTableList = pmTableList.Where(a => a != null).ToList();
|
|
|
+ systemTableList = systemTableList.Where(a => a != null).ToList();
|
|
|
+ DataTable pm = new DataTable();
|
|
|
+ DataTable system = new DataTable();
|
|
|
+
|
|
|
+ if (pmTableList != null && pmTableList.Count > 0)
|
|
|
+ pm = MergeDataTables(pmTableList, pmTableList.FirstOrDefault().Columns.Cast<DataColumn>().Select(c => c.ColumnName).ToList());
|
|
|
+
|
|
|
+ if (systemTableList != null && systemTableList.Count > 0)
|
|
|
+ system = MergeDataTables(systemTableList, systemTableList.FirstOrDefault().Columns.Cast<DataColumn>().Select(c => c.ColumnName).ToList());
|
|
|
+
|
|
|
+
|
|
|
+ SaveDataToTable(pm, system, fileName, pmList, systemList, startTime, endTime, recipeInfo);
|
|
|
}
|
|
|
|
|
|
private bool firstHeader = false;
|
|
@@ -629,247 +653,160 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
|
|
|
}
|
|
|
public class NeedCellColor
|
|
|
{
|
|
|
+ /// <summary>
|
|
|
+ /// 是否需要单元格颜色
|
|
|
+ /// </summary>
|
|
|
public bool IsNeed;
|
|
|
+ /// <summary>
|
|
|
+ /// 配置项中的Color 数据,只支持16进制
|
|
|
+ /// </summary>
|
|
|
public string Color;
|
|
|
- public short FillForegroundColor;
|
|
|
- public FillPattern FillPatternShort;
|
|
|
- }
|
|
|
- private ICellStyle GetICellStyle(IWorkbook workbook, NeedCellColor needCellColor = null)
|
|
|
- {
|
|
|
- ICellStyle cellStyle = workbook.CreateCellStyle();
|
|
|
- cellStyle.WrapText = true;
|
|
|
- cellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
|
|
|
- cellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
|
|
|
- cellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
|
|
|
- cellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
|
|
|
- cellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
|
|
|
- cellStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
|
|
|
-
|
|
|
- if (needCellColor != null && needCellColor.IsNeed)
|
|
|
- {
|
|
|
- //string hexColor = needCellColor.Color;
|
|
|
- //short colorIndex = GetCustomPaletteColor(workbook, hexColor);
|
|
|
- cellStyle.FillForegroundColor = needCellColor.FillForegroundColor;
|
|
|
- cellStyle.FillPattern = needCellColor.FillPatternShort;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- return cellStyle;
|
|
|
|
|
|
}
|
|
|
- static short GetCustomPaletteColor(IWorkbook workbook, string hexColor)
|
|
|
+ private static System.Drawing.Color ParseHexColor(string hexColor)
|
|
|
{
|
|
|
- if (hexColor.StartsWith("#"))
|
|
|
- {
|
|
|
- hexColor = hexColor.Substring(1);
|
|
|
- }
|
|
|
+ // 移除 #
|
|
|
+ hexColor = hexColor.Replace("#", "").Trim();
|
|
|
|
|
|
- int red = Convert.ToInt32(hexColor.Substring(0, 2), 16);
|
|
|
- int green = Convert.ToInt32(hexColor.Substring(2, 2), 16);
|
|
|
- int blue = Convert.ToInt32(hexColor.Substring(4, 2), 16);
|
|
|
+ if (!ColorUtil.IsValidHexColor(hexColor))
|
|
|
+ return System.Drawing.Color.Transparent;
|
|
|
|
|
|
- HSSFWorkbook hssfWorkbook = (HSSFWorkbook)workbook;
|
|
|
- HSSFPalette palette = hssfWorkbook.GetCustomPalette();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
- return palette.FindSimilarColor((byte)red, (byte)green, (byte)blue).Indexed;
|
|
|
+ byte r = Convert.ToByte(hexColor.Substring(0, 2), 16);
|
|
|
+ byte g = Convert.ToByte(hexColor.Substring(2, 2), 16);
|
|
|
+ byte b = Convert.ToByte(hexColor.Substring(4, 2), 16);
|
|
|
+
|
|
|
+ return System.Drawing.Color.FromArgb(r, g, b);
|
|
|
}
|
|
|
- catch (Exception)
|
|
|
+ catch (Exception ex)
|
|
|
{
|
|
|
- // 如果找不到相似的颜色,则分配新的调色板索引
|
|
|
- HSSFColor customColor = palette.FindColor((byte)red, (byte)green, (byte)blue);
|
|
|
- if (customColor == null)
|
|
|
- {
|
|
|
- customColor = palette.AddColor((byte)red, (byte)green, (byte)blue);
|
|
|
- }
|
|
|
- return customColor.Indexed;
|
|
|
+ return System.Drawing.Color.Transparent;
|
|
|
}
|
|
|
}
|
|
|
- private void SaveDataToTable(string fileName, List<string> pmList, List<string> systemList, DateTime startTime, DateTime endTime, ProcessHistoryLot recipeInfo)
|
|
|
- {
|
|
|
- string stepID = "", stepName = "", subRecipeLoopInfo = "", subRecipeStepName = "", subRecipeStepNumber = "", tempCorrection = "", tempPid = "";
|
|
|
-
|
|
|
- DataTable pmDataTable = null;
|
|
|
|
|
|
|
|
|
- var columnsql = $"select column_name from information_schema.columns where table_name = '{startTime.ToString("yyyyMMdd")}.PM1'";
|
|
|
- var columnTable = QueryDataClient.Instance.Service.QueryData(columnsql);
|
|
|
- List<string> col = columnTable.Rows.Cast<DataRow>().Select(x => x.ItemArray[0].ToString()).ToList();
|
|
|
- pmList = pmList.Where(x => col.Any(y => y == x)).ToList();
|
|
|
+ private void SaveDataToTable(DataTable pmDataTable, DataTable systemDataTable, string fileName, List<string> pmList, List<string> systemList, DateTime startTime, DateTime endTime, ProcessHistoryLot recipeInfo)
|
|
|
+ {
|
|
|
+ int numData = 35;
|
|
|
+ var time = DateTime.Now;
|
|
|
|
|
|
- string pmsql = $"select time AS InternalTimeStamp, {string.Join(",", pmList.Select(x => string.Format("\"{0}\"", x)))}";
|
|
|
- DataTable systemDataTable = null;
|
|
|
- pmsql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc",
|
|
|
- startTime.ToString("yyyyMMdd") + "." + "PM1", startTime.Ticks, endTime.Ticks);
|
|
|
- BusyIndicatorContent = "Example Query PM data ...";
|
|
|
- pmDataTable = QueryDataClient.Instance.Service.QueryData(pmsql);
|
|
|
-
|
|
|
-
|
|
|
- var sysColumnsql = $"select column_name from information_schema.columns where table_name = '{startTime.ToString("yyyyMMdd")}.System'";
|
|
|
- var sysColumnTable = QueryDataClient.Instance.Service.QueryData(sysColumnsql);
|
|
|
- List<string> systemCol = sysColumnTable?.Rows.Cast<DataRow>().Select(x => x.ItemArray[0].ToString()).ToList();
|
|
|
- systemList = systemList.Where(x => systemCol.Any(y => y == x)).ToList();
|
|
|
- string systemsql = $"select time AS InternalTimeStamp, {string.Join(",", systemList.Select(x => string.Format("\"{0}\"", x)))}";
|
|
|
- systemsql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc",
|
|
|
- startTime.ToString("yyyyMMdd") + "." + "System", startTime.Ticks, endTime.Ticks);
|
|
|
- BusyIndicatorContent = "Example Query System data ...";
|
|
|
- systemDataTable = QueryDataClient.Instance.Service.QueryData(systemsql);
|
|
|
- int maxRow = 0;
|
|
|
- if ((pmDataTable == null || pmDataTable.Rows.Count == 0))
|
|
|
- {
|
|
|
- if (systemDataTable != null)
|
|
|
- {
|
|
|
- maxRow = systemDataTable.Rows.Count;
|
|
|
- }
|
|
|
- }
|
|
|
- else if ((systemDataTable == null || systemDataTable.Rows.Count == 0))
|
|
|
- {
|
|
|
- if (pmDataTable != null)
|
|
|
- {
|
|
|
- maxRow = pmDataTable.Rows.Count;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- maxRow = pmDataTable.Rows.Count > systemDataTable.Rows.Count ? systemDataTable.Rows.Count : pmDataTable.Rows.Count;
|
|
|
- }
|
|
|
|
|
|
- var subColNames = new List<DataColumn>() {
|
|
|
- new DataColumn("Step\nStartDate"),
|
|
|
- new DataColumn("Step\nStartTime"),
|
|
|
- new DataColumn("\tStepID\t "),
|
|
|
- new DataColumn("\tStepName\t"),
|
|
|
- new DataColumn("SubRecipe\nStepName"),
|
|
|
- new DataColumn("SubRecipe\nStepNumber"),
|
|
|
- new DataColumn("SubRecipe\nLoopInfo"),
|
|
|
- new DataColumn("Temp\nCorrection"),
|
|
|
- new DataColumn("\tTempPID\t"),
|
|
|
- };
|
|
|
+ string stepID = "", stepName = "", subRecipeLoopInfo = "", subRecipeStepName = "", subRecipeStepNumber = "", tempCorrection = "", tempPid = "";
|
|
|
|
|
|
+ int maxRow = GetMaxRow(pmDataTable, systemDataTable);
|
|
|
|
|
|
- // Create a new workbook and sheet
|
|
|
IWorkbook workbook = new XSSFWorkbook();
|
|
|
ISheet sheet = workbook.CreateSheet("Sheet1");
|
|
|
- #region style
|
|
|
-
|
|
|
+
|
|
|
+ #region Recipe 信息
|
|
|
|
|
|
+ int rowIndex = 0;
|
|
|
+ int cellIndex = 0;
|
|
|
|
|
|
- ICellStyle borderCellStyle = workbook.CreateCellStyle();
|
|
|
- borderCellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
|
|
|
- borderCellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
|
|
|
- borderCellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
|
|
|
- borderCellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
|
|
|
+ Dictionary<string, string> keyValuePairs = new Dictionary<string, string>()
|
|
|
+ {
|
|
|
+ { "Recipe Info",recipeInfo.RecipeName},
|
|
|
+ { "Recipe StartTime",recipeInfo.ProcessStartTime.ToString(DateTimeUtil.DateTimeFormat)},
|
|
|
+ { "Recipe EndTime",recipeInfo.ProcessEndTime.ToString(DateTimeUtil.DateTimeFormat)},
|
|
|
+ { "Recipe Type",recipeInfo.RecipeType.ToString()},
|
|
|
+ { "Recipe ExecEntry",recipeInfo.RecipeExecEntry.ToString()},
|
|
|
+ };
|
|
|
|
|
|
- IFont font = workbook.CreateFont();
|
|
|
+ IRow dictRow = sheet.CreateRow(0);
|
|
|
+ IRow dictRowTwo = sheet.CreateRow(1);
|
|
|
+ dictRow.HeightInPoints = numData;
|
|
|
+ dictRowTwo.HeightInPoints = numData;
|
|
|
+ foreach (var kvp in keyValuePairs)
|
|
|
+ {
|
|
|
+ var RecipeCellIndex = cellIndex++;
|
|
|
+ WriterCell(dictRow, RecipeCellIndex, workbook, kvp.Key, GetICellStyle(workbook));
|
|
|
+ WriterCell(dictRowTwo, RecipeCellIndex, workbook, kvp.Value, GetICellStyle(workbook));
|
|
|
|
|
|
- borderCellStyle.SetFont(font);
|
|
|
- borderCellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
|
|
|
- borderCellStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
|
|
|
+ }
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
- int rowIndex = 4;
|
|
|
- int cellIndex = 0;
|
|
|
+ #region 数据列表头信息
|
|
|
+
|
|
|
+ rowIndex = 4;
|
|
|
+ cellIndex = 0;
|
|
|
+
|
|
|
if (!firstHeader)
|
|
|
{
|
|
|
- firstHeader = true;
|
|
|
- var systemColNames = systemDataTable?.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp").Select(x =>
|
|
|
+ Dictionary<string, string> subColNames = new Dictionary<string, string>()
|
|
|
{
|
|
|
- if (_processProcessDetailAttributeDict.ContainsKey(x.ColumnName))
|
|
|
- {
|
|
|
- var colAttributeName = "ColName";
|
|
|
- if (!_processProcessDetailAttributeDict[x.ColumnName].ContainsKey(colAttributeName))
|
|
|
- {
|
|
|
- colAttributeName = "DisplayName";
|
|
|
- }
|
|
|
- var tempStr = _processProcessDetailAttributeDict[x.ColumnName].ContainsKey("DisplayName") && !string.IsNullOrEmpty(_processProcessDetailAttributeDict[x.ColumnName]["DisplayName"]) ? _processProcessDetailAttributeDict[x.ColumnName]["DisplayName"] : x.ColumnName;
|
|
|
- return string.IsNullOrEmpty(_processProcessDetailAttributeDict[x.ColumnName][colAttributeName]) ? x.ColumnName : _processProcessDetailAttributeDict[x.ColumnName][colAttributeName];
|
|
|
- }
|
|
|
- return x.ColumnName;
|
|
|
- });
|
|
|
+ { "Step\nStartDate",ColorUtil.Color_Defalult},
|
|
|
+ { "Step\nStartTime",ColorUtil.Color_Defalult},
|
|
|
+ { "\tStepID\t ",ColorUtil.Color_Defalult},
|
|
|
+ { "\tStepName\t",ColorUtil.Color_Defalult},
|
|
|
+ { "SubRecipe\nStepName",ColorUtil.Color_Defalult},
|
|
|
+ { "SubRecipe\nStepNumber",ColorUtil.Color_Defalult},
|
|
|
+ { "SubRecipe\nLoopInfo",ColorUtil.Color_Defalult},
|
|
|
+ { "Temp\nCorrection",ColorUtil.Color_Yellow},
|
|
|
+ { "\tTempPID\t",ColorUtil.Color_Yellow},
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ firstHeader = true;
|
|
|
+ var colColorNameDict = GetColNameColor(pmDataTable, systemDataTable);
|
|
|
+
|
|
|
+
|
|
|
+ var pmColorDict = colColorNameDict.Item1;
|
|
|
+ var systemmColorDict = colColorNameDict.Item2;
|
|
|
|
|
|
- var pmColNames = pmDataTable?.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp").Select(x =>
|
|
|
- {
|
|
|
- if (_processProcessDetailAttributeDict.ContainsKey(x.ColumnName))
|
|
|
- {
|
|
|
- var colAttributeName = "ColName";
|
|
|
- if (!_processProcessDetailAttributeDict[x.ColumnName].ContainsKey(colAttributeName))
|
|
|
- {
|
|
|
- colAttributeName = "DisplayName";
|
|
|
- }
|
|
|
- var tempStr = _processProcessDetailAttributeDict[x.ColumnName].ContainsKey("DisplayName") && !string.IsNullOrEmpty(_processProcessDetailAttributeDict[x.ColumnName]["DisplayName"]) ? _processProcessDetailAttributeDict[x.ColumnName]["DisplayName"] : x.ColumnName;
|
|
|
- return string.IsNullOrEmpty(_processProcessDetailAttributeDict[x.ColumnName][colAttributeName]) ? x.ColumnName : _processProcessDetailAttributeDict[x.ColumnName][colAttributeName];
|
|
|
- }
|
|
|
- return x.ColumnName;
|
|
|
- });
|
|
|
|
|
|
- // Create header row
|
|
|
IRow headerRow = sheet.CreateRow(rowIndex++);
|
|
|
cellIndex = 0;
|
|
|
- headerRow.HeightInPoints = 35;
|
|
|
- foreach (var subCol in subColNames)
|
|
|
+ headerRow.HeightInPoints = numData;
|
|
|
+ foreach (var item in subColNames)
|
|
|
{
|
|
|
- ICell cell = headerRow.CreateCell(cellIndex++);
|
|
|
-
|
|
|
- string headerText = subCol.ColumnName.Replace("(", "\n(");
|
|
|
- cell.SetCellValue(headerText);
|
|
|
- cell.CellStyle = GetICellStyle(workbook);
|
|
|
- sheet.SetColumnWidth(cell.ColumnIndex, subCol.ColumnName.Length * 256);
|
|
|
+ var dataCellIndex = cellIndex++;
|
|
|
+ var needCellColor = new NeedCellColor() { IsNeed = false };
|
|
|
+ if (subColNames.TryGetValue(item.Key, out var dataColor) && ColorUtil.IsValidHexColor(dataColor))
|
|
|
+ {
|
|
|
+ needCellColor.IsNeed = true;
|
|
|
+ needCellColor.Color = dataColor;
|
|
|
+ }
|
|
|
+ WriterCell(headerRow, dataCellIndex, workbook, item.Key.Replace("(", "\n("), GetICellStyle(workbook, needCellColor));
|
|
|
+ sheet.SetColumnWidth(dataCellIndex, 22 * 256);
|
|
|
}
|
|
|
|
|
|
- foreach (var sysCol in systemColNames ?? new string[0])
|
|
|
+ foreach (var item in systemmColorDict.Keys)
|
|
|
{
|
|
|
- ICell cell = headerRow.CreateCell(cellIndex++);
|
|
|
- string headerText = sysCol.Replace("(", "\n(");
|
|
|
- cell.SetCellValue(headerText);
|
|
|
- cell.CellStyle = GetICellStyle(workbook);
|
|
|
- sheet.SetColumnWidth(cell.ColumnIndex, sysCol.Length * 256);
|
|
|
+ var dataCellIndex = cellIndex++;
|
|
|
+ var needCellColor = new NeedCellColor() { IsNeed = false };
|
|
|
+ if (systemmColorDict.TryGetValue(item, out var dataColor) && ColorUtil.IsValidHexColor(dataColor))
|
|
|
+ {
|
|
|
+ needCellColor.IsNeed = true;
|
|
|
+ needCellColor.Color = dataColor;
|
|
|
+ }
|
|
|
+ WriterCell(headerRow, dataCellIndex, workbook, item.Replace("(", "\n("), GetICellStyle(workbook, needCellColor));
|
|
|
+ sheet.SetColumnWidth(dataCellIndex, item.Length * 256);
|
|
|
}
|
|
|
|
|
|
- foreach (var pmCol in pmColNames ?? new string[0])
|
|
|
+ foreach (var item in pmColorDict.Keys)
|
|
|
{
|
|
|
- ICell cell = headerRow.CreateCell(cellIndex++);
|
|
|
- string headerText = pmCol.Replace("(", "\n(");
|
|
|
- cell.SetCellValue(headerText);
|
|
|
- cell.CellStyle = GetICellStyle(workbook);
|
|
|
- sheet.SetColumnWidth(cell.ColumnIndex, pmCol.Length * 256);
|
|
|
+ var dataCellIndex = cellIndex++;
|
|
|
+ var needCellColor = new NeedCellColor() { IsNeed = false };
|
|
|
+ if (pmColorDict.TryGetValue(item, out var dataColor) && ColorUtil.IsValidHexColor(dataColor))
|
|
|
+ {
|
|
|
+ needCellColor.IsNeed = true;
|
|
|
+ needCellColor.Color = dataColor;
|
|
|
+ }
|
|
|
+ WriterCell(headerRow, dataCellIndex, workbook, item.Replace("(", "\n("), GetICellStyle(workbook));
|
|
|
+ sheet.SetColumnWidth(dataCellIndex, item.Length * 256);
|
|
|
}
|
|
|
}
|
|
|
+ #endregion
|
|
|
+
|
|
|
+
|
|
|
+ #region 数据列 行数据信息
|
|
|
|
|
|
- Dictionary<string, string> keyValuePairs = new Dictionary<string, string>()
|
|
|
- {
|
|
|
- { "Recipe Info",recipeInfo.RecipeName},
|
|
|
- { "Recipe StartTime",recipeInfo.ProcessStartTime.ToString("yyyy-MM-dd HH:mm:ss")},
|
|
|
- { "Recipe EndTime",recipeInfo.ProcessEndTime.ToString("yyyy-MM-dd HH:mm:ss")},
|
|
|
- { "Recipe Type",recipeInfo.RecipeType.ToString()},
|
|
|
- { "Recipe ExecEntry",recipeInfo.RecipeExecEntry.ToString()},
|
|
|
- };
|
|
|
- rowIndex = 0;
|
|
|
- cellIndex = 0;
|
|
|
- IRow dictRow = sheet.CreateRow(rowIndex);
|
|
|
- dictRow.HeightInPoints = 35;
|
|
|
- foreach (var kvp in keyValuePairs)
|
|
|
- {
|
|
|
- ICell keyCell = dictRow.CreateCell(cellIndex++);
|
|
|
- keyCell.SetCellValue(kvp.Key);
|
|
|
- keyCell.CellStyle = GetICellStyle(workbook);
|
|
|
- }
|
|
|
|
|
|
- rowIndex = 1;
|
|
|
- cellIndex = 0;
|
|
|
- dictRow = sheet.CreateRow(rowIndex);
|
|
|
- dictRow.HeightInPoints = 35;
|
|
|
- foreach (var kvp in keyValuePairs)
|
|
|
- {
|
|
|
- ICell keyCell = dictRow.CreateCell(cellIndex++);
|
|
|
- keyCell.SetCellValue(kvp.Value);
|
|
|
- keyCell.CellStyle = GetICellStyle(workbook);
|
|
|
- //sheet.AutoSizeColumn(cellIndex);
|
|
|
- sheet.SetColumnWidth(cellIndex - 1, kvp.Value.Length * 256);
|
|
|
- }
|
|
|
- int columnIndex = subColNames.Count + 1;
|
|
|
rowIndex = 5;
|
|
|
+ _stepInfo = _stepInfo.OrderByDescending(x => x.StartTime).ToList();
|
|
|
|
|
|
for (int i = 0; i < maxRow; i++)
|
|
|
{
|
|
@@ -880,7 +817,7 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
|
|
|
|
|
|
DateTime dateTimeKey = new DateTime(systemRow != null ? (long)systemRow[0] : (long)pmRow[0]);
|
|
|
|
|
|
- var tempStepInfo = _stepInfo.OrderByDescending(x => x.StartTime).Where(x => x.StartTime <= dateTimeKey).FirstOrDefault();
|
|
|
+ var tempStepInfo = _stepInfo.FirstOrDefault(x => x.StartTime <= dateTimeKey);
|
|
|
|
|
|
if (tempStepInfo != null)
|
|
|
{
|
|
@@ -895,8 +832,8 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
|
|
|
|
|
|
cellIndex = 0;
|
|
|
|
|
|
- dataRow.CreateCell(cellIndex++).SetCellValue(dateTimeKey.ToString("yyyy/MM/dd"));
|
|
|
- dataRow.CreateCell(cellIndex++).SetCellValue(dateTimeKey.ToString("HH:mm:ss"));
|
|
|
+ dataRow.CreateCell(cellIndex++).SetCellValue(dateTimeKey.ToString(DateTimeUtil.DateFormat));
|
|
|
+ dataRow.CreateCell(cellIndex++).SetCellValue(dateTimeKey.ToString(DateTimeUtil.TimeFormat));
|
|
|
dataRow.CreateCell(cellIndex++).SetCellValue(stepID);
|
|
|
dataRow.CreateCell(cellIndex++).SetCellValue(stepName);
|
|
|
dataRow.CreateCell(cellIndex++).SetCellValue(subRecipeStepName);
|
|
@@ -908,67 +845,271 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
|
|
|
{
|
|
|
for (int j = 1; j < systemRow.ItemArray.Length; j++)
|
|
|
{
|
|
|
- ICell cell = dataRow.CreateCell(cellIndex++);
|
|
|
- cell.SetCellValue(systemRow[j].ToString());
|
|
|
- cell.CellStyle = GetICellStyle(workbook);
|
|
|
+ WriterCell(dataRow, cellIndex++, workbook, systemRow[j].ToString());
|
|
|
}
|
|
|
for (int j = 0; j < (pmDataTable?.Columns.Count ?? 0); j++)
|
|
|
{
|
|
|
- ICell cell = dataRow.CreateCell(cellIndex++);
|
|
|
- cell.SetCellValue("");
|
|
|
- cell.CellStyle = GetICellStyle(workbook);
|
|
|
+ WriterCell(dataRow, cellIndex++, workbook, "");
|
|
|
}
|
|
|
}
|
|
|
else if (pmRow != null && systemRow == null)
|
|
|
{
|
|
|
+
|
|
|
for (int j = 0; j < (systemDataTable?.Columns?.Count ?? 0); j++)
|
|
|
{
|
|
|
- ICell cell = dataRow.CreateCell(cellIndex++);
|
|
|
- cell.SetCellValue("");
|
|
|
- cell.CellStyle = GetICellStyle(workbook);
|
|
|
+ WriterCell(dataRow, cellIndex++, workbook, "");
|
|
|
}
|
|
|
for (int j = 1; j < pmRow.ItemArray.Length; j++)
|
|
|
{
|
|
|
- ICell cell = dataRow.CreateCell(cellIndex++);
|
|
|
-
|
|
|
- var setValueData = pmRow[j].ToString();
|
|
|
- if (bool.TryParse(pmRow[j].ToString(), out var avData))
|
|
|
- setValueData = pmRow[j].ToString() == bool.TrueString ? "Open" : "Close";
|
|
|
-
|
|
|
- cell.SetCellValue(setValueData);
|
|
|
- cell.CellStyle = GetICellStyle(workbook);
|
|
|
+ WriterCell(dataRow, cellIndex++, workbook, ConvertBooleanValues(pmRow[j]));
|
|
|
}
|
|
|
}
|
|
|
else if (systemDataTable != null)
|
|
|
{
|
|
|
for (int j = 1; j < systemRow.ItemArray.Length; j++)
|
|
|
{
|
|
|
- ICell cell = dataRow.CreateCell(cellIndex++);
|
|
|
- cell.SetCellValue(systemRow[j].ToString());
|
|
|
- cell.CellStyle = GetICellStyle(workbook);
|
|
|
+ WriterCell(dataRow, cellIndex++, workbook, systemRow[j].ToString());
|
|
|
}
|
|
|
for (int j = 1; j < pmRow.ItemArray.Length; j++)
|
|
|
{
|
|
|
- ICell cell = dataRow.CreateCell(cellIndex++);
|
|
|
- var setValueData = pmRow[j].ToString();
|
|
|
- if (bool.TryParse(pmRow[j].ToString(), out var avData))
|
|
|
- setValueData = pmRow[j].ToString() == bool.TrueString ? "Open" : "Close";
|
|
|
+ WriterCell(dataRow, cellIndex++, workbook, ConvertBooleanValues(pmRow[j]));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
|
|
|
- cell.SetCellValue(setValueData);
|
|
|
- cell.CellStyle = GetICellStyle(workbook);
|
|
|
+
|
|
|
+ sheet.CreateFreezePane(4, 5);
|
|
|
+
|
|
|
+ using (MemoryStream memoryStream = new MemoryStream())
|
|
|
+ {
|
|
|
+ workbook.Write(memoryStream);
|
|
|
+ File.WriteAllBytes(fileName, memoryStream.ToArray());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ #region 抽离方法
|
|
|
+ private ICellStyle GetICellStyle(IWorkbook workbook, NeedCellColor needCellColor = null)
|
|
|
+ {
|
|
|
+ ICellStyle cellStyle = workbook.CreateCellStyle();
|
|
|
+ cellStyle.WrapText = true;
|
|
|
+ cellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
|
|
|
+ cellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
|
|
|
+ cellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
|
|
|
+ cellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;//粗线
|
|
|
+ cellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
|
|
|
+ cellStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
|
|
|
+
|
|
|
+ if (needCellColor != null && needCellColor.IsNeed)
|
|
|
+ {
|
|
|
+ string hexColor = needCellColor.Color;
|
|
|
+ XSSFColor colorIndex = new XSSFColor(ParseHexColor(hexColor));
|
|
|
+
|
|
|
+ ((XSSFCellStyle)cellStyle).SetFillForegroundColor(colorIndex);
|
|
|
+ cellStyle.FillPattern = FillPattern.SolidForeground;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return cellStyle;
|
|
|
+
|
|
|
+ }
|
|
|
+ private string ConvertBooleanValues(object value)
|
|
|
+ {
|
|
|
+ if (bool.TryParse(value.ToString(), out bool avData))
|
|
|
+ {
|
|
|
+ return avData ? "Open" : "Close";
|
|
|
+ }
|
|
|
+ return value.ToString();
|
|
|
+ }
|
|
|
+ private DataTable MergeDataTables(List<DataTable> tables, List<string> commonColumns)
|
|
|
+ {
|
|
|
+ if (!tables.Any()) return new DataTable();
|
|
|
+
|
|
|
+ DataTable result = new DataTable();
|
|
|
+
|
|
|
+ // 添加列(确保顺序一致)
|
|
|
+ foreach (var colName in commonColumns)
|
|
|
+ {
|
|
|
+ var sampleCol = tables[0].Columns[colName];
|
|
|
+ result.Columns.Add(colName, sampleCol.DataType);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 合并每一行
|
|
|
+ foreach (var table in tables)
|
|
|
+ {
|
|
|
+ foreach (DataRow row in table.Rows)
|
|
|
+ {
|
|
|
+ var newRow = result.NewRow();
|
|
|
+ foreach (var colName in commonColumns)
|
|
|
+ {
|
|
|
+ if (row[colName] != DBNull.Value)
|
|
|
+ newRow[colName] = row[colName];
|
|
|
+ else
|
|
|
+ newRow[colName] = DBNull.Value;
|
|
|
}
|
|
|
+ result.Rows.Add(newRow);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 排序最终结果(按时间戳)
|
|
|
+ DataView view = result.DefaultView;
|
|
|
+ view.Sort = "InternalTimeStamp ASC";
|
|
|
+
|
|
|
+ return view.ToTable();
|
|
|
+ }
|
|
|
+
|
|
|
+ public DataTable GetDataTable(ModuleName type, List<string> queryColNameList, DateTime startTime, DateTime endTime)
|
|
|
+ {
|
|
|
+ var tableName = ModuleName.PM1.ToString();
|
|
|
+
|
|
|
+ if (type == ModuleName.System)
|
|
|
+ tableName = ModuleName.System.ToString();
|
|
|
+
|
|
|
+
|
|
|
+ DataTable resultTable = null;
|
|
|
+ var columnsql = $"select column_name from information_schema.columns where table_name = '{startTime.ToString("yyyyMMdd")}.{tableName}'";
|
|
|
+ var columnTable = QueryDataClient.Instance.Service.QueryData(columnsql);
|
|
|
+ List<string> col = columnTable.Rows.Cast<DataRow>().Select(x => x.ItemArray[0].ToString()).ToList();
|
|
|
+
|
|
|
+ queryColNameList = queryColNameList.Where(x => col.Any(y => y == x)).ToList();
|
|
|
+ var tableColName = queryColNameList.Select(x => string.Format("\"{0}\"", x));
|
|
|
+
|
|
|
+ string pmsql = $"select time AS InternalTimeStamp, {string.Join(",", tableColName)}";
|
|
|
+ pmsql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc",
|
|
|
+ startTime.ToString("yyyyMMdd") + "." + $"{tableName}", startTime.Ticks, endTime.Ticks);
|
|
|
+ BusyIndicatorContent = $"Example Query {tableName} data ...";
|
|
|
+ resultTable = QueryDataClient.Instance.Service.QueryData(pmsql);
|
|
|
+
|
|
|
+ return resultTable;
|
|
|
+
|
|
|
+ }
|
|
|
+ private int GetMaxRow(DataTable pmDataTable, DataTable systemDataTable)
|
|
|
+ {
|
|
|
+
|
|
|
+ int maxRow = 0;
|
|
|
+ if ((pmDataTable == null || pmDataTable.Rows.Count == 0))
|
|
|
+ {
|
|
|
+ if (systemDataTable != null)
|
|
|
+ {
|
|
|
+ maxRow = systemDataTable.Rows.Count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if ((systemDataTable == null || systemDataTable.Rows.Count == 0))
|
|
|
+ {
|
|
|
+ if (pmDataTable != null)
|
|
|
+ {
|
|
|
+ maxRow = pmDataTable.Rows.Count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ maxRow = pmDataTable.Rows.Count > systemDataTable.Rows.Count ? systemDataTable.Rows.Count : pmDataTable.Rows.Count;
|
|
|
+ }
|
|
|
+ return maxRow;
|
|
|
+ }
|
|
|
+ private Tuple<Dictionary<string, string>, Dictionary<string, string>> GetColNameColor(DataTable pmDataTable, DataTable systemDataTable)
|
|
|
+ {
|
|
|
+ Dictionary<string, string> systemColorNameDict = new Dictionary<string, string>();
|
|
|
+ foreach (var item in systemDataTable?.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp"))
|
|
|
+ {
|
|
|
+ if (!_processProcessDetailAttributeDict.ContainsKey(item.ColumnName))
|
|
|
+ {
|
|
|
+ systemColorNameDict.Add(item.ColumnName, "");
|
|
|
+ continue;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ var colAttributeName = "ColName";
|
|
|
+ if (!_processProcessDetailAttributeDict[item.ColumnName].ContainsKey(colAttributeName))
|
|
|
+ {
|
|
|
+ colAttributeName = "DisplayName";
|
|
|
+ }
|
|
|
+ var tempStr = _processProcessDetailAttributeDict[item.ColumnName].ContainsKey("DisplayName") && !string.IsNullOrEmpty(_processProcessDetailAttributeDict[item.ColumnName]["DisplayName"]) ? _processProcessDetailAttributeDict[item.ColumnName]["DisplayName"] : item.ColumnName;
|
|
|
+ var resultName = string.IsNullOrEmpty(_processProcessDetailAttributeDict[item.ColumnName][colAttributeName]) ? item.ColumnName : _processProcessDetailAttributeDict[item.ColumnName][colAttributeName];
|
|
|
+
|
|
|
+ colAttributeName = "Color";
|
|
|
+ var resultColor = "";
|
|
|
+ if (_processProcessDetailAttributeDict[item.ColumnName].ContainsKey(colAttributeName))
|
|
|
+ resultColor = string.IsNullOrEmpty(_processProcessDetailAttributeDict[item.ColumnName][colAttributeName]) ? "" : _processProcessDetailAttributeDict[item.ColumnName][colAttributeName];
|
|
|
+
|
|
|
+ systemColorNameDict.Add(resultName, resultColor);
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
- sheet.SetColumnWidth(0, keyValuePairs.LastOrDefault().Key.Length * 256);
|
|
|
- sheet.SetColumnWidth(3, keyValuePairs.LastOrDefault().Key.Length * 256);
|
|
|
- sheet.SetColumnWidth(4, keyValuePairs.LastOrDefault().Key.Length * 256);
|
|
|
- // Write the output to a file
|
|
|
- using (FileStream file = new FileStream(fileName, FileMode.Create, FileAccess.Write))
|
|
|
+ Dictionary<string, string> pmColorNameDict = new Dictionary<string, string>();
|
|
|
+ foreach (var item in pmDataTable?.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp"))
|
|
|
{
|
|
|
- workbook.Write(file);
|
|
|
+ if (!_processProcessDetailAttributeDict.ContainsKey(item.ColumnName))
|
|
|
+ {
|
|
|
+ pmColorNameDict.Add(item.ColumnName, "");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ var colAttributeName = "ColName";
|
|
|
+ if (!_processProcessDetailAttributeDict[item.ColumnName].ContainsKey(colAttributeName))
|
|
|
+ {
|
|
|
+ colAttributeName = "DisplayName";
|
|
|
+ }
|
|
|
+ var tempStr = _processProcessDetailAttributeDict[item.ColumnName].ContainsKey("DisplayName") && !string.IsNullOrEmpty(_processProcessDetailAttributeDict[item.ColumnName]["DisplayName"]) ? _processProcessDetailAttributeDict[item.ColumnName]["DisplayName"] : item.ColumnName;
|
|
|
+ var resultName = string.IsNullOrEmpty(_processProcessDetailAttributeDict[item.ColumnName][colAttributeName]) ? item.ColumnName : _processProcessDetailAttributeDict[item.ColumnName][colAttributeName];
|
|
|
+ colAttributeName = "Color";
|
|
|
+ var resultColor = "";
|
|
|
+ if (_processProcessDetailAttributeDict[item.ColumnName].ContainsKey(colAttributeName))
|
|
|
+ resultColor = string.IsNullOrEmpty(_processProcessDetailAttributeDict[item.ColumnName][colAttributeName]) ? "" : _processProcessDetailAttributeDict[item.ColumnName][colAttributeName];
|
|
|
+
|
|
|
+ pmColorNameDict.Add(resultName, resultColor);
|
|
|
}
|
|
|
+
|
|
|
+ return new Tuple<Dictionary<string, string>, Dictionary<string, string>>(pmColorNameDict, systemColorNameDict);
|
|
|
+
|
|
|
+ }
|
|
|
+ private Tuple<IEnumerable<string>, IEnumerable<string>> GetColName(DataTable pmDataTable, DataTable systemDataTable)
|
|
|
+ {
|
|
|
+
|
|
|
+ var systemColNames = systemDataTable?.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp").Select(x =>
|
|
|
+ {
|
|
|
+ if (_processProcessDetailAttributeDict.ContainsKey(x.ColumnName))
|
|
|
+ {
|
|
|
+ var colAttributeName = "ColName";
|
|
|
+ if (!_processProcessDetailAttributeDict[x.ColumnName].ContainsKey(colAttributeName))
|
|
|
+ {
|
|
|
+ colAttributeName = "DisplayName";
|
|
|
+ }
|
|
|
+ var tempStr = _processProcessDetailAttributeDict[x.ColumnName].ContainsKey("DisplayName") && !string.IsNullOrEmpty(_processProcessDetailAttributeDict[x.ColumnName]["DisplayName"]) ? _processProcessDetailAttributeDict[x.ColumnName]["DisplayName"] : x.ColumnName;
|
|
|
+ return string.IsNullOrEmpty(_processProcessDetailAttributeDict[x.ColumnName][colAttributeName]) ? x.ColumnName : _processProcessDetailAttributeDict[x.ColumnName][colAttributeName];
|
|
|
+ }
|
|
|
+ return x.ColumnName;
|
|
|
+ });
|
|
|
+
|
|
|
+ var pmColNames = pmDataTable?.Columns.Cast<DataColumn>().Where(x => x.ColumnName != "internaltimestamp").Select(x =>
|
|
|
+ {
|
|
|
+ if (_processProcessDetailAttributeDict.ContainsKey(x.ColumnName))
|
|
|
+ {
|
|
|
+ var colAttributeName = "ColName";
|
|
|
+ if (!_processProcessDetailAttributeDict[x.ColumnName].ContainsKey(colAttributeName))
|
|
|
+ {
|
|
|
+ colAttributeName = "DisplayName";
|
|
|
+ }
|
|
|
+ var tempStr = _processProcessDetailAttributeDict[x.ColumnName].ContainsKey("DisplayName") && !string.IsNullOrEmpty(_processProcessDetailAttributeDict[x.ColumnName]["DisplayName"]) ? _processProcessDetailAttributeDict[x.ColumnName]["DisplayName"] : x.ColumnName;
|
|
|
+ return string.IsNullOrEmpty(_processProcessDetailAttributeDict[x.ColumnName][colAttributeName]) ? x.ColumnName : _processProcessDetailAttributeDict[x.ColumnName][colAttributeName];
|
|
|
+ }
|
|
|
+ return x.ColumnName;
|
|
|
+ });
|
|
|
+
|
|
|
+ return new Tuple<IEnumerable<string>, IEnumerable<string>>(pmColNames, systemColNames);
|
|
|
}
|
|
|
|
|
|
+ private void WriterCell(IRow row, int cellIndex, IWorkbook workbook, string setValue, ICellStyle cellStyle = null)
|
|
|
+ {
|
|
|
+ ICell keyCell = row.CreateCell(cellIndex);
|
|
|
+ keyCell.SetCellValue(setValue);
|
|
|
+ keyCell.CellStyle = cellStyle;
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
static string CheckAndReplace(string input)
|
|
|
{
|
|
|
if (input.StartsWith("PM1"))
|