using Microsoft.EntityFrameworkCore; using Microsoft.Win32; using OfficeOpenXml; using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; namespace MembranePoreTester.Views { public partial class HistoryWindow : Window { public int? SelectedStation { get; set; } // 传入当前工位ID public HistoryWindow() { InitializeComponent(); } private void Query_Click(object sender, RoutedEventArgs e) { using var db = new AppDbContext(); var query = new List(); // 获取泡点法记录 var bubblePoints = db.BubblePointRecords .Select(b => new { b.Id, b.StationId, Type = "泡点法", b.TestDate, b.SampleType, b.SampleSpec, b.Tester, Result = $"最大孔径: {b.MaxPoreSize:F3} μm" }); query.AddRange(bubblePoints); // 获取孔分布记录 var poreDistributions = db.PoreDistributionRecords .Select(p => new { p.Id, p.StationId, Type = "孔分布", p.TestDate, p.SampleType, p.SampleSpec, p.Tester, Result = $"平均孔径: {p.AveragePoreSize:F3} μm" }); query.AddRange(poreDistributions); // 过滤工位 if (cmbStation.SelectedIndex > 0) { int station = cmbStation.SelectedIndex; query = query.Where(x => ((dynamic)x).StationId == station).ToList(); } // 过滤类型 if (cmbType.SelectedIndex == 1) query = query.Where(x => ((dynamic)x).Type == "泡点法").ToList(); else if (cmbType.SelectedIndex == 2) query = query.Where(x => ((dynamic)x).Type == "孔分布").ToList(); // 过滤日期范围 if (dpStart.SelectedDate != null) query = query.Where(x => ((dynamic)x).TestDate >= dpStart.SelectedDate).ToList(); if (dpEnd.SelectedDate != null) query = query.Where(x => ((dynamic)x).TestDate <= dpEnd.SelectedDate.Value.AddDays(1)).ToList(); dgHistory.ItemsSource = query.OrderByDescending(x => ((dynamic)x).TestDate).ToList(); } //private void ExportSelected_Click(object sender, RoutedEventArgs e) //{ // if (dgHistory.SelectedItem == null) // { // MessageBox.Show("请先选中一条记录"); // return; // } // dynamic selected = dgHistory.SelectedItem; // int id = selected.Id; // string type = selected.Type; // var saveFileDialog = new SaveFileDialog // { // Filter = "Excel文件|*.xlsx", // FileName = $"{type}_{id}.xlsx" // }; // if (saveFileDialog.ShowDialog() == true) // { // if (type == "泡点法") // { // using var db = new AppDbContext(); // var entity = db.BubblePointRecords.Find(id); // if (entity != null) // { // ExportHelper.ExportBubblePoint(entity, saveFileDialog.FileName); // } // } // else // { // using var db = new AppDbContext(); // var entity = db.PoreDistributionRecords // .Include(p => p.DataPoints) // .FirstOrDefault(p => p.Id == id); // if (entity != null) // { // ExportHelper.ExportPoreDistribution(entity, saveFileDialog.FileName); // } // } // } //} private void ExportSelected_Click(object sender, RoutedEventArgs e) { ExcelPackage.LicenseContext = LicenseContext.NonCommercial; if (dgHistory.SelectedItems.Count == 0) { MessageBox.Show("请至少选中一条记录", "提示", MessageBoxButton.OK, MessageBoxImage.Information); return; } var saveFileDialog = new SaveFileDialog { Filter = "Excel文件|*.xlsx", FileName = $"历史记录_{DateTime.Now:yyyyMMddHHmmss}.xlsx" }; if (saveFileDialog.ShowDialog() != true) return; using var package = new OfficeOpenXml.ExcelPackage(); int sheetIndex = 1; foreach (dynamic selected in dgHistory.SelectedItems) { int id = selected.Id; string type = selected.Type; string sheetName = $"{type}_{id}"; // Excel 工作表名称长度限制 31 字符,且不能包含特殊字符 sheetName = new string(sheetName.Take(31).ToArray()).Replace('/', '_').Replace('\\', '_').Replace('?', '_').Replace('*', '_').Replace('[', '_').Replace(']', '_'); using var db = new AppDbContext(); if (type == "泡点法") { var entity = db.BubblePointRecords.Find(id); if (entity != null) { var sheet = package.Workbook.Worksheets.Add(sheetName); // 使用辅助方法填充数据到工作表 FillBubblePointSheet(sheet, entity); } } else if (type == "孔分布") { var entity = db.PoreDistributionRecords .Include(p => p.DataPoints) .FirstOrDefault(p => p.Id == id); if (entity != null) { var sheet = package.Workbook.Worksheets.Add(sheetName); FillPoreDistributionSheet(sheet, entity); } } sheetIndex++; } package.SaveAs(saveFileDialog.FileName); MessageBox.Show($"成功导出 {dgHistory.SelectedItems.Count} 条记录到文件", "导出完成", MessageBoxButton.OK, MessageBoxImage.Information); } private void FillBubblePointSheet(OfficeOpenXml.ExcelWorksheet sheet, BubblePointEntity entity) { sheet.Cells["A1"].Value = "工位"; sheet.Cells["B1"].Value = entity.StationId; sheet.Cells["A2"].Value = "测试日期"; sheet.Cells["B2"].Value = entity.TestDate.ToString("yyyy-MM-dd HH:mm:ss"); sheet.Cells["A3"].Value = "测试者"; sheet.Cells["B3"].Value = entity.Tester; sheet.Cells["A4"].Value = "样品类型"; sheet.Cells["B4"].Value = entity.SampleType; sheet.Cells["A5"].Value = "规格"; sheet.Cells["B5"].Value = entity.SampleSpec; sheet.Cells["A6"].Value = "室温(°C)"; sheet.Cells["B6"].Value = entity.RoomTemperature; sheet.Cells["A7"].Value = "浸润时间(h)"; sheet.Cells["B7"].Value = entity.SoakingTime; sheet.Cells["A8"].Value = "测试液体"; sheet.Cells["B8"].Value = entity.LiquidName; sheet.Cells["A9"].Value = "液体生产厂家"; sheet.Cells["B9"].Value = entity.LiquidManufacturer; sheet.Cells["A10"].Value = "泡点压力"; sheet.Cells["B10"].Value = $"{entity.BubblePointPressure} {entity.PressureUnit}"; sheet.Cells["A11"].Value = "最大孔径(μm)"; sheet.Cells["B11"].Value = entity.MaxPoreSize; sheet.Cells.AutoFitColumns(); } private void FillPoreDistributionSheet(OfficeOpenXml.ExcelWorksheet sheet, PoreDistributionEntity entity) { sheet.Cells["A1"].Value = "工位"; sheet.Cells["B1"].Value = entity.StationId; sheet.Cells["A2"].Value = "测试日期"; sheet.Cells["B2"].Value = entity.TestDate.ToString("yyyy-MM-dd HH:mm:ss"); sheet.Cells["A3"].Value = "测试者"; sheet.Cells["B3"].Value = entity.Tester; sheet.Cells["A4"].Value = "样品类型"; sheet.Cells["B4"].Value = entity.SampleType; sheet.Cells["A5"].Value = "规格"; sheet.Cells["B5"].Value = entity.SampleSpec; sheet.Cells["A6"].Value = "室温(°C)"; sheet.Cells["B6"].Value = entity.RoomTemperature; sheet.Cells["A7"].Value = "浸润时间(h)"; sheet.Cells["B7"].Value = entity.SoakingTime; sheet.Cells["A8"].Value = "测试液体"; sheet.Cells["B8"].Value = entity.LiquidName; sheet.Cells["A9"].Value = "液体生产厂家"; sheet.Cells["B9"].Value = entity.LiquidManufacturer; sheet.Cells["A10"].Value = "泡点压力"; sheet.Cells["B10"].Value = $"{entity.BubblePointPressure} {entity.PressureUnit}"; sheet.Cells["A11"].Value = "平均孔径(μm)"; sheet.Cells["B11"].Value = entity.AveragePoreSize; // 数据点表格 sheet.Cells["A13"].Value = "压力(kPa)"; sheet.Cells["B13"].Value = "湿膜流量(L/min)"; sheet.Cells["C13"].Value = "干膜流量(L/min)"; int row = 14; foreach (var dp in entity.DataPoints) { sheet.Cells[$"A{row}"].Value = dp.Pressure; sheet.Cells[$"B{row}"].Value = dp.WetFlow; sheet.Cells[$"C{row}"].Value = dp.DryFlow; row++; } sheet.Cells.AutoFitColumns(); } private void LoadToCurrentStation_Click(object sender, RoutedEventArgs e) { if (dgHistory.SelectedItem == null) return; if (SelectedStation == null) { MessageBox.Show("未指定当前工位"); return; } dynamic selected = dgHistory.SelectedItem; int id = selected.Id; string type = selected.Type; // 通过事件或回调将记录加载到当前工位 // 这里需要与主窗口交互,简单起见,我们使用静态事件 LoadRecordEvent?.Invoke(this, new LoadRecordEventArgs { RecordId = id, Type = type, TargetStation = SelectedStation.Value }); DialogResult = true; Close(); } private void Close_Click(object sender, RoutedEventArgs e) => Close(); public static event EventHandler LoadRecordEvent; private void Window_Loaded(object sender, RoutedEventArgs e) { Query_Click(sender, e); } } public class LoadRecordEventArgs : EventArgs { public int RecordId { get; set; } public string Type { get; set; } public int TargetStation { get; set; } } }