diff --git a/App.xaml.cs b/App.xaml.cs index f0253f5..bfb81d5 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -1,8 +1,9 @@ -using System; +using MembranePoreTester.Communication; +using Microsoft.Extensions.Configuration; +using OfficeOpenXml; +using System; using System.IO; using System.Windows; -using MembranePoreTester.Communication; -using Microsoft.Extensions.Configuration; namespace MembranePoreTester { @@ -13,6 +14,9 @@ namespace MembranePoreTester protected async override void OnStartup(StartupEventArgs e) { + + ExcelPackage.LicenseContext = LicenseContext.NonCommercial; + base.OnStartup(e); using var db = new AppDbContext(); diff --git a/Views/HistoryWindow.xaml b/Views/HistoryWindow.xaml index 9ebb627..18ecbaf 100644 --- a/Views/HistoryWindow.xaml +++ b/Views/HistoryWindow.xaml @@ -122,7 +122,7 @@ diff --git a/Views/HistoryWindow.xaml.cs b/Views/HistoryWindow.xaml.cs index 96667dc..0d77bc9 100644 --- a/Views/HistoryWindow.xaml.cs +++ b/Views/HistoryWindow.xaml.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Win32; +using OfficeOpenXml; using System; using System.Collections.Generic; using System.Linq; @@ -74,49 +75,178 @@ namespace MembranePoreTester.Views 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) { - if (dgHistory.SelectedItem == null) + ExcelPackage.LicenseContext = LicenseContext.NonCommercial; + if (dgHistory.SelectedItems.Count == 0) { - MessageBox.Show("请先选中一条记录"); + MessageBox.Show("请至少选中一条记录", "提示", MessageBoxButton.OK, MessageBoxImage.Information); return; } - dynamic selected = dgHistory.SelectedItem; - int id = selected.Id; - string type = selected.Type; - var saveFileDialog = new SaveFileDialog { Filter = "Excel文件|*.xlsx", - FileName = $"{type}_{id}.xlsx" + FileName = $"历史记录_{DateTime.Now:yyyyMMddHHmmss}.xlsx" }; - if (saveFileDialog.ShowDialog() == true) + 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 == "泡点法") { - using var db = new AppDbContext(); var entity = db.BubblePointRecords.Find(id); if (entity != null) { - ExportHelper.ExportBubblePoint(entity, saveFileDialog.FileName); + var sheet = package.Workbook.Worksheets.Add(sheetName); + // 使用辅助方法填充数据到工作表 + FillBubblePointSheet(sheet, entity); } } - else + else if (type == "孔分布") { - 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); + 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;