From 9d1660270272180cd71147d6ddd53d1382643d2e Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期一, 02 十一月 2026 18:00:14 +0800
Subject: [PATCH] merge: 并入远程 Initial commit 作为历史根节点

---
 Plugin.QualityReport/QualityReport.xaml.cs |  705 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 705 insertions(+), 0 deletions(-)

diff --git a/Plugin.QualityReport/QualityReport.xaml.cs b/Plugin.QualityReport/QualityReport.xaml.cs
new file mode 100644
index 0000000..538968c
--- /dev/null
+++ b/Plugin.QualityReport/QualityReport.xaml.cs
@@ -0,0 +1,705 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using HMI.Base;
+using HMI.Core.Entity;
+using HMI.Core.Manager;
+using HMI.Core.Setting;
+using HMI.Core.Util;
+using HMI.UI.Util;
+using Microsoft.Win32;
+using NPOI.HSSF.UserModel;
+using NPOI.SS.UserModel;
+using NPOI.Util;
+using NPOI.XSSF.UserModel;
+using Panuon.WPF.UI;
+using System.Collections.ObjectModel;
+using System.Data;
+using System.IO;
+using System.Windows;
+
+namespace Plugin.QualityReport
+{
+    public class CMKData
+    {
+        public object[] values = new object[5];
+        public object d1 { get => values[0]; set => values[0] = value; }
+        public object d2 { get => values[1]; set => values[1] = value; }
+        public object d3 { get => values[2]; set => values[2] = value; }
+        public object d4 { get => values[3]; set => values[3] = value; }
+        public object d5 { get => values[4]; set => values[4] = value; }
+    }
+
+    public class MSAData
+    {
+        public object[] values = new object[9];
+        public object d1 { get => values[0]; set => values[0] = value; }
+        public object d2 { get => values[1]; set => values[1] = value; }
+        public object d3 { get => values[2]; set => values[2] = value; }
+        public object d4 { get => values[3]; set => values[3] = value; }
+        public object d5 { get => values[4]; set => values[4] = value; }
+        public object d6 { get => values[5]; set => values[5] = value; }
+        public object d7 { get => values[6]; set => values[6] = value; }
+        public object d8 { get => values[7]; set => values[7] = value; }
+        public object d9 { get => values[8]; set => values[8] = value; }
+    }
+
+    public class RepeatData
+    {
+        public string Title { get; set; }
+
+        public object[] values = new object[10];
+        public object d1 { get => values[0]; set => values[0] = value; }
+        public object d2 { get => values[1]; set => values[1] = value; }
+        public object d3 { get => values[2]; set => values[2] = value; }
+        public object d4 { get => values[3]; set => values[3] = value; }
+        public object d5 { get => values[4]; set => values[4] = value; }
+        public object d6 { get => values[5]; set => values[5] = value; }
+        public object d7 { get => values[6]; set => values[6] = value; }
+        public object d8 { get => values[7]; set => values[7] = value; }
+        public object d9 { get => values[8]; set => values[8] = value; }
+        public object d10 { get => values[9]; set => values[9] = value; }
+    }
+
+    /// <summary>
+    /// QualityReport.xaml 鐨勪氦浜掗�昏緫
+    /// </summary>
+    [ObservableObject]
+    public partial class QualityReport : SimpleMaskControl
+    {
+        [ObservableProperty]
+        private string model;
+
+        [ObservableProperty]
+        private List<ProductData> models;
+
+        [ObservableProperty]
+        private DateTime startTimeCMK;
+
+        [ObservableProperty]
+        private DateTime endTimeCMK;
+
+        [ObservableProperty]
+        private string testItemCMK = "TestItem";
+
+        [ObservableProperty]
+        private List<CMKData> datasourceCMK = null;
+
+        [ObservableProperty]
+        private List<MSAData> datasourceMSA = null;
+
+        [ObservableProperty]
+        private List<RepeatData> datasourceRepeat = null;
+
+        [ObservableProperty]
+        private string snr;
+
+        [ObservableProperty]
+        private ObservableCollection<string> selectedSnr = new ObservableCollection<string> { };
+
+        [ObservableProperty]
+        private ObservableCollection<string> selectedSnrRepeat = new ObservableCollection<string> { };
+
+        public QualityReport()
+        {
+            DataContext = this;
+            InitializeComponent();
+            StartTimeCMK = DateTime.Today;
+            EndTimeCMK = DateTime.Today.AddDays(1);
+        }
+
+        public override void Active()
+        {
+            base.Active();
+            Models = ProductManager.GetProducts<List<ProductData>>()
+                ?? new List<ProductData>();
+        }
+
+        private string[] GetFiles(DateTime? startTime, DateTime? endTime)
+        {
+            string dir = ParamSetting.DataLogFolder;
+            string startName = $"Data_{startTime?.ToString("yyyyMMdd")}";
+            string endName = $"Data_{endTime?.ToString("yyyyMMdd")}";
+            var oldFiles = Directory.GetFiles(dir, "Data_*.db");
+            oldFiles = oldFiles.Where(file =>
+            {
+                var fileName = Path.GetFileNameWithoutExtension(file);
+                bool flag = true;
+                flag &= (string.Compare(fileName, startName) == 1 || fileName == startName);
+                flag &= (string.Compare(endName, fileName) == 1 || fileName == endName);
+                return flag;
+            }).ToArray();
+            return oldFiles;
+        }
+
+        public DataTable SelectByFiles(string[] files, Func<string, string, string> ConcatAction, SortParam sorter, PageParam page)
+        {
+            if (files == null || files.Length <= 0)
+            {
+                return new DataTable();
+            }
+            if (files.Length < Sqlite3Helper.MAX_ATTACHED)
+            {
+                using (var helper = new Sqlite3Helper(files[0]))
+                {
+                    string[] sqls = new string[files.Length];
+                    for (int i = 0; i < files.Length; i++)
+                    {
+                        var attach = $"ATTACH DATABASE '{files[i]}' AS 'db{i}'";
+                        helper.Execute(attach);
+                        sqls[i] = ConcatAction(files[i], $"db{i}");
+                    }
+                    string sql = string.Join(" UNION ALL ", sqls);
+
+                    sql = $"SELECT * FROM ({sql}) as _temp";
+                    if (sorter != null)
+                    {
+                        sql = $"{sql} ORDER BY {sorter.field} {sorter.sort}";
+                    }
+                    if (page != null)
+                    {
+                        sql = $"{sql} LIMIT {page.limit} OFFSET {page.offset}";
+                    }
+                    return helper.GetDataTable(sql);
+                }
+            }
+            else
+            {
+                DataTable dt = new DataTable();
+                Sqlite3Helper helper = null;
+                string[] sqls = new string[Sqlite3Helper.MAX_ATTACHED];
+
+                var fff = () =>
+                {
+                    if (helper != null)
+                    {
+                        string sql = string.Join(" UNION ALL ", sqls.Where(s => s != null));
+
+                        sql = $"SELECT * FROM ({sql}) as _temp";
+
+
+                        dt.Merge(helper.GetDataTable(sql));
+                        sqls = new string[Sqlite3Helper.MAX_ATTACHED];
+                        helper.Dispose();
+                        helper = null;
+                    }
+                };
+
+                try
+                {
+                    for (int i = 0; i < files.Length; i++)
+                    {
+                        if (i % Sqlite3Helper.MAX_ATTACHED == 0)
+                        {
+                            fff();
+                            helper = new Sqlite3Helper(files[i]);
+                        }
+                        var attach = $"ATTACH DATABASE '{files[i]}' AS 'db{i}'";
+                        helper.Execute(attach);
+                        sqls[i % Sqlite3Helper.MAX_ATTACHED] = ConcatAction(files[i], $"db{i}");
+                    }
+                    fff();
+                    if (dt.Rows.Count > 0)
+                    {
+                        if (sorter != null)
+                        {
+                            dt.DefaultView.Sort = $"{sorter.field} {sorter.sort}";
+                        }
+                        if (page != null)
+                        {
+                            var rows = dt.Rows.Cast<DataRow>();
+                            var curRows = rows.Skip(page.offset).Take(page.limit).ToArray();
+                            var sb = dt.Clone();
+                            if (dt.Rows.Count > page.offset)
+                            {
+                                if (dt.Rows.Count < page.limit)
+                                {
+                                    sb = dt;
+                                }
+                                else
+                                {
+                                    for (int i = page.offset; i < page.offset + page.limit; i++)
+                                    {
+                                        sb.ImportRow(dt.Rows[i]);
+                                    }
+                                }
+                            }
+                            dt = sb;
+                            // dt = new DataTable(curRows);
+                        }
+                    }
+                }
+                finally
+                {
+                    helper?.Dispose();
+                }
+                return dt;
+            }
+        }
+
+
+        [RelayCommand]
+        public void QueryCMK()
+        {
+            try
+            {
+                if (string.IsNullOrEmpty(Model) || string.IsNullOrEmpty(TestItemCMK) || StartTimeCMK == null || EndTimeCMK == null)
+                {
+                    ToastHelper.Error("璇疯緭鍏ュ瀷鍙枫�佹祴璇曢」銆佸紑濮嬫椂闂村拰缁撴潫鏃堕棿锛�");
+                    return;
+                }
+                string[] files = GetFiles(StartTimeCMK, EndTimeCMK);
+
+
+                DataTable dt = SelectByFiles(files, (file, db) =>
+                {
+                    return $"SELECT value,time FROM {db}.serialData WHERE model='{Model}' AND step='{TestItemCMK}' AND time>='{StartTimeCMK:yyyy-MM-dd HH:mm:ss}' AND time<'{EndTimeCMK:yyyy-MM-dd HH:mm:ss}'";
+                }, new SortParam { field = "time", sort = "DESC" }, new PageParam { limit = 50, offset = 0 });
+                List<CMKData> list = new List<CMKData>();
+                object[] values = null;
+                for (int i = 0; i < dt.Rows.Count; i++)
+                {
+                    if (i % 5 == 0)
+                    {
+                        values = new object[5];
+                        list.Add(new CMKData { values = values });
+                    }
+                    values[i % 5] = dt.Rows[i]["value"];
+                }
+                DatasourceCMK = list;
+            }
+            catch (Exception ex)
+            {
+
+            }
+        }
+
+        [RelayCommand]
+        public void ExportCMK()
+        {
+            try
+            {
+                if (string.IsNullOrEmpty(Model) || string.IsNullOrEmpty(TestItemCMK) || StartTimeCMK == null || EndTimeCMK == null)
+                {
+                    ToastHelper.Error("璇疯緭鍏ュ瀷鍙枫�佹祴璇曢」銆佸紑濮嬫椂闂村拰缁撴潫鏃堕棿锛�");
+                    return;
+                }
+                string[] files = GetFiles(StartTimeCMK, EndTimeCMK);
+
+
+                DataTable dt = SelectByFiles(files, (file, db) =>
+                {
+                    return $"SELECT value,time FROM {db}.serialData WHERE model='{Model}' AND step='{TestItemCMK}' AND time>='{StartTimeCMK:yyyy-MM-dd HH:mm:ss}' AND time<'{EndTimeCMK:yyyy-MM-dd HH:mm:ss}'";
+                }, new SortParam { field = "time", sort = "DESC" }, new PageParam { limit = 50, offset = 0 });
+                List<CMKData> list = new List<CMKData>();
+                object[] values = null;
+                for (int i = 0; i < dt.Rows.Count; i++)
+                {
+                    if (i % 5 == 0)
+                    {
+                        values = new object[5];
+                        list.Add(new CMKData { values = values });
+                    }
+                    values[i % 5] = dt.Rows[i]["value"];
+                }
+
+                using (FileStream fs = File.OpenRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Libs", "Static", "CMK妯℃澘.xls")))
+                {
+                    IWorkbook workbook = new HSSFWorkbook(fs);
+                    ISheet sheet = workbook.GetSheet("CMK");
+                    for (int i = 0; i < list.Count; i++)
+                    {
+                        int num = i + 9;
+                        if (num > 24)
+                        {
+                            break;
+                        }
+                        IRow row = sheet.GetRow(num);
+                        CMKData data = list[i];
+                        for (int j = 0; j < 5; j++)
+                        {
+                            if (data.values[j] != null)
+                            {
+                                row.GetCell(j).SetCellValue(double.Parse(data.values[j].ToString()));
+                            }
+                        }
+                    }
+                    sheet.ForceFormulaRecalculation = true;//鎵ц鍏紡
+
+                    //鏂规硶浜�
+                    //workbook.GetCreationHelper().CreateFormulaEvaluator().EvaluateAll();
+
+                    SaveFileDialog sfd = new SaveFileDialog
+                    {
+                        Filter = "Excel鏂囦欢 (*.xls)|*.xls",
+                    };
+                    if (sfd.ShowDialog() == true)
+                    {
+                        using (FileStream sfs = new FileStream(sfd.FileName, FileMode.OpenOrCreate))
+                        {
+                            workbook.Write(sfs);
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+
+            }
+        }
+
+        [RelayCommand]
+        private void AddSnr()
+        {
+            if (SelectedSnr.Count >= 9)
+            {
+                ToastHelper.Warning("鏈�澶氶�夊彇9涓骇鍝�");
+                return;
+            }
+
+            if (SelectedSnr.Contains(Snr))
+            {
+                ToastHelper.Warning($"鏉$爜锛歔{Snr}] 宸茶閫変腑");
+                return;
+            }
+            SelectedSnr.Add(Snr);
+        }
+
+        [RelayCommand]
+        private void AddSnr2Repeat()
+        {
+            if (SelectedSnrRepeat.Count >= 10)
+            {
+                ToastHelper.Warning("鏈�澶氶�夊彇10涓骇鍝�");
+                return;
+            }
+
+            if (SelectedSnrRepeat.Contains(Snr))
+            {
+                ToastHelper.Warning($"鏉$爜锛歔{Snr}] 宸茶閫変腑");
+                return;
+            }
+            SelectedSnrRepeat.Add(Snr);
+        }
+
+        [RelayCommand]
+        public void RemoveSN(object obj)
+        {
+            SelectedSnr.Remove(obj.ToString());
+        }
+
+        [RelayCommand]
+        public void QueryMSA()
+        {
+            try
+            {
+                if (string.IsNullOrEmpty(Model) || SelectedSnr.Count <= 0 || StartTimeCMK == null || EndTimeCMK == null)
+                {
+                    ToastHelper.Error("璇疯緭鍏ュ瀷鍙枫�侀�変腑鐨勬潯鐮併�佸紑濮嬫椂闂村拰缁撴潫鏃堕棿锛�");
+                    return;
+                }
+                string[] files = GetFiles(StartTimeCMK, EndTimeCMK);
+                Dictionary<string, List<int>> map = new Dictionary<string, List<int>>();
+                foreach (var sn in SelectedSnr)
+                {
+                    List<int> datas = new List<int>();
+                    DataTable dt = SelectByFiles(files, (file, db) =>
+                {
+                    return $"SELECT result,time FROM {db}.testResult WHERE model='{Model}' AND sn='{sn}' AND time>='{StartTimeCMK:yyyy-MM-dd HH:mm:ss}' AND time<'{EndTimeCMK:yyyy-MM-dd HH:mm:ss}'";
+                }, new SortParam { field = "time", sort = "DESC" }, new PageParam { limit = 10, offset = 0 });
+
+                    datas = dt.Rows.Cast<DataRow>().Select(r =>
+                    string.Equals(r["result"].ToString(), "passed", StringComparison.OrdinalIgnoreCase)
+                    || string.Equals(r["result"].ToString(), "ok", StringComparison.OrdinalIgnoreCase) ? 1 : 0)
+                        .ToList();
+                    map[sn] = datas;
+                }
+                List<MSAData> temp = new List<MSAData>() { new MSAData() };
+
+                int i = 0;
+                foreach (var key in map.Keys)
+                {
+                    temp[0].values[i] = key;
+                    var vals = map[key];
+                    for (int j = 0; j < vals.Count; j++)
+                    {
+                        if (temp.Count < j + 2)
+                        {
+                            temp.Add(new MSAData());
+                        }
+                        temp[j + 1].values[i] = vals[j];
+                    }
+                    i++;
+                }
+                DatasourceMSA = temp;
+
+                //RefreshMSAGrid(map);
+            }
+            catch (Exception ex)
+            {
+
+            }
+        }
+
+
+        [RelayCommand]
+        public void ExportMSA()
+        {
+            try
+            {
+                if (string.IsNullOrEmpty(Model) || SelectedSnr.Count <= 0 || StartTimeCMK == null || EndTimeCMK == null)
+                {
+                    ToastHelper.Error("璇疯緭鍏ュ瀷鍙枫�侀�変腑鐨勬潯鐮併�佸紑濮嬫椂闂村拰缁撴潫鏃堕棿锛�");
+                    return;
+                }
+
+                string[] files = GetFiles(StartTimeCMK, EndTimeCMK);
+                Dictionary<string, List<int>> map = new Dictionary<string, List<int>>();
+                foreach (var sn in SelectedSnr)
+                {
+                    List<int> datas = new List<int>();
+                    DataTable dt = SelectByFiles(files, (file, db) =>
+                    {
+                        return $"SELECT result,time FROM {db}.testResult WHERE model='{Model}' AND sn='{sn}' AND time>='{StartTimeCMK:yyyy-MM-dd HH:mm:ss}' AND time<'{EndTimeCMK:yyyy-MM-dd HH:mm:ss}'";
+                    }, new SortParam { field = "time", sort = "DESC" }, new PageParam { limit = 10, offset = 0 });
+
+                    datas = dt.Rows.Cast<DataRow>().Select(r =>
+                    string.Equals(r["result"].ToString(), "passed", StringComparison.OrdinalIgnoreCase)
+                    || string.Equals(r["result"].ToString(), "ok", StringComparison.OrdinalIgnoreCase) ? 1 : 0)
+                        .ToList();
+                    map[sn] = datas;
+                }
+                using (FileStream fs = File.OpenRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Libs", "Static", "MSA妯℃澘.xlsx")))
+                {
+                    IWorkbook workbook = new XSSFWorkbook(fs);
+                    ISheet sheet = workbook.GetSheet("鏁版嵁杈撳叆");
+
+                    int column = 2;
+                    foreach (string snr in map.Keys)
+                    {
+                        if (column > 10)
+                        {
+                            break;
+                        }
+                        var datas = map[snr];
+                        sheet.GetRow(9).GetCell(column).SetCellValue(snr);
+
+                        for (int i = 0; i < datas.Count; i++)
+                        {
+                            if (i > 49) break;
+                            sheet.GetRow(i + 11).GetCell(column).SetCellValue(datas[i]);
+                        }
+                        column++;
+                    }
+                    sheet.ForceFormulaRecalculation = true;//鎵ц鍏紡
+
+                    //鏂规硶浜�
+                    //workbook.GetCreationHelper().CreateFormulaEvaluator().EvaluateAll();
+
+                    SaveFileDialog sfd = new SaveFileDialog
+                    {
+                        Filter = "Excel鏂囦欢 (*.xlsx)|*.xlsx",
+                    };
+                    if (sfd.ShowDialog() == true)
+                    {
+                        using (FileStream sfs = new FileStream(sfd.FileName, FileMode.OpenOrCreate))
+                        {
+                            workbook.Write(sfs);
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+
+            }
+        }
+
+        [RelayCommand]
+        public void QueryRepeat()
+        {
+            try
+            {
+                if (string.IsNullOrEmpty(Model) || SelectedSnrRepeat.Count <= 0 || string.IsNullOrEmpty(TestItemCMK) || StartTimeCMK == null || EndTimeCMK == null)
+                {
+                    ToastHelper.Error("璇疯緭鍏ュ瀷鍙枫�侀�変腑鐨勬潯鐮併�佹祴璇曢」銆佸紑濮嬫椂闂村拰缁撴潫鏃堕棿锛�");
+                    return;
+                }
+
+                string[] files = GetFiles(StartTimeCMK, EndTimeCMK);
+                Dictionary<string, List<double>> map = new Dictionary<string, List<double>>();
+                foreach (var sn in SelectedSnrRepeat)
+                {
+                    DataTable dt = SelectByFiles(files, (file, db) =>
+                    {
+                        return $"SELECT value,time FROM {db}.serialData WHERE model='{Model}' And step='{TestItemCMK}' AND sn='{sn}' AND time>='{StartTimeCMK:yyyy-MM-dd HH:mm:ss}' AND time<'{EndTimeCMK:yyyy-MM-dd HH:mm:ss}'";
+                    }, new SortParam { field = "time", sort = "DESC" }, new PageParam { limit = 9, offset = 0 });
+
+                    var datas = dt.Rows.Cast<DataRow>().Select(r => Math.Round(double.Parse(r["value"].ToString()), 3, MidpointRounding.AwayFromZero)).ToList();
+                    map[sn] = datas;
+                }
+                List<RepeatData> temp = new List<RepeatData>() { new RepeatData { Title = "鏉$爜" } };
+
+                int i = 0;
+                foreach (var key in map.Keys)
+                {
+                    temp[0].values[i] = key;
+                    var vals = map[key];
+                    for (int j = 0; j < vals.Count; j++)
+                    {
+                        if (temp.Count < j + 2)
+                        {
+                            temp.Add(new RepeatData());
+                        }
+                        temp[j + 1].values[i] = vals[j];
+                    }
+                    i++;
+                }
+                DatasourceRepeat = temp;
+            }
+            catch (Exception ex)
+            {
+                log.Error("閲嶅鎬ф煡璇㈠け璐�", ex);
+                MsgBoxHelper2.Error($"閲嶅鎬ф煡璇㈠け璐�: {ex.Message}");
+            }
+        }
+
+
+        [RelayCommand]
+        public void ExportRepeat()
+        {
+            try
+            {
+                if (string.IsNullOrEmpty(Model) || SelectedSnrRepeat.Count <= 0 || string.IsNullOrEmpty(TestItemCMK) || StartTimeCMK == null || EndTimeCMK == null)
+                {
+                    ToastHelper.Error("璇疯緭鍏ュ瀷鍙枫�侀�変腑鐨勬潯鐮併�佹祴璇曢」銆佸紑濮嬫椂闂村拰缁撴潫鏃堕棿锛�");
+                    return;
+                }
+                string[] files = GetFiles(StartTimeCMK, EndTimeCMK);
+                Dictionary<string, List<double>> map = new Dictionary<string, List<double>>();
+                foreach (var sn in SelectedSnrRepeat)
+                {
+                    DataTable dt = SelectByFiles(files, (file, db) =>
+                    {
+                        return $"SELECT value,time FROM {db}.serialData WHERE model='{Model}' And step='{TestItemCMK}' AND sn='{sn}' AND time>='{StartTimeCMK:yyyy-MM-dd HH:mm:ss}' AND time<'{EndTimeCMK:yyyy-MM-dd HH:mm:ss}'";
+                    }, new SortParam { field = "time", sort = "DESC" }, new PageParam { limit = 9, offset = 0 });
+
+                    var datas = dt.Rows.Cast<DataRow>().Select(r => Math.Round(double.Parse(r["value"].ToString()), 3, MidpointRounding.AwayFromZero)).ToList();
+                    map[sn] = datas;
+                }
+                List<RepeatData> temp = new List<RepeatData>() { new RepeatData() };
+
+                int i = 0;
+                foreach (var key in map.Keys)
+                {
+                    temp[0].values[i] = key;
+                    var vals = map[key];
+                    for (int j = 0; j < vals.Count; j++)
+                    {
+                        if (temp.Count < j + 2)
+                        {
+                            temp.Add(new RepeatData());
+                        }
+                        temp[j + 1].values[i] = vals[j];
+                    }
+                    i++;
+                }
+
+                using (FileStream fs = File.OpenRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Libs", "Static", "閲嶅鎬фā鏉�.xls")))
+                {
+                    IWorkbook workbook = new HSSFWorkbook(fs);
+                    ISheet sheet = workbook.GetSheet("sheet1");
+
+                    sheet.GetRow(10).GetCell(2).SetCellValue(TestItemCMK);
+
+                    int column = 2;
+                    foreach (string snr in map.Keys)
+                    {
+                        if (column > 11)
+                        {
+                            break;
+                        }
+                        var datas = map[snr];
+                        sheet.GetRow(11).GetCell(column).SetCellValue(snr);
+
+                        for (int j = 0; j < datas.Count; j++)
+                        {
+                            if (j > 8) break;
+                            int row = j + 13;
+                            if (j > 2 && j <= 5)
+                            {
+                                row = j + 15;
+                            }
+                            else if (j > 5)
+                            {
+                                row = j + 17;
+                            }
+                            sheet.GetRow(row).GetCell(column).SetCellValue(datas[j]);
+                        }
+                        column++;
+                    }
+                    sheet.ForceFormulaRecalculation = true;//鎵ц鍏紡
+
+                    //鏂规硶浜�
+                    //workbook.GetCreationHelper().CreateFormulaEvaluator().EvaluateAll();
+
+                    SaveFileDialog sfd = new SaveFileDialog
+                    {
+                        Filter = "Excel鏂囦欢 (*.xls)|*.xls",
+                    };
+                    if (sfd.ShowDialog() == true)
+                    {
+                        using (FileStream sfs = new FileStream(sfd.FileName, FileMode.OpenOrCreate))
+                        {
+                            workbook.Write(sfs);
+                            ToastHelper.Success("瀵煎嚭鎴愬姛");
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Error("閲嶅鎬у鍑哄け璐�", ex);
+                MsgBoxHelper2.Error($"瀵煎嚭澶辫触: {ex.Message}");
+            }
+        }
+
+        private void SearchTextChanged(object sender, Panuon.WPF.SearchTextChangedRoutedEventArgs e)
+        {
+            SearchBox box = (SearchBox)sender;
+            try
+            {
+                string[] files = GetFiles(StartTimeCMK, EndTimeCMK).OrderBy(s => s).Take(7).ToArray();
+
+                if (box.Tag.ToString() == "Step")
+                {
+                    DataTable dt = SelectByFiles(files, (file, db) =>
+                    {
+                        return $"SELECT DISTINCT step FROM {db}.serialData WHERE model='{Model}' And step LIKE '%{TestItemCMK}%'";
+                    }, null, null);
+
+                    var datas = dt.Rows.Cast<DataRow>().Select(r => r["step"].ToString()).Distinct().ToList();
+                    box.ItemsSource = datas;
+                }
+                else
+                {
+                    DataTable dt = SelectByFiles(files, (file, db) =>
+                    {
+                        return $"SELECT DISTINCT sn FROM {db}.testResult WHERE model='{Model}' And sn LIKE '%{Snr}%'";
+                    }, null, null);
+
+                    var datas = dt.Rows.Cast<DataRow>().Select(r => r["sn"].ToString()).Distinct().ToList();
+                    box.ItemsSource = datas;
+                }
+            }
+            catch
+            {
+                box.ItemsSource = new string[] { };
+            }
+        }
+
+        private void Button_Click(object sender, RoutedEventArgs e)
+        {
+
+        }
+    }
+}

--
Gitblit v1.9.1