using Dapper; using Modbus.Device; using MySql.Data.MySqlClient; using System; using System.Collections.ObjectModel; using System.Configuration; using System.IO; using System.Net.Sockets; using System.Text; using System.Windows; using System.Windows.Controls; using 自救器呼吸器综合检验仪.Data; namespace 自救器呼吸器综合检验仪 { public static class DatabaseConfig { public static string ConnectionString => ConfigurationManager.ConnectionStrings["MySqlConnection"].ConnectionString; } public partial class ReportWindow2 : Window { private MainWindow2 _mainWindow2; private ReportWindow2 _reportWindow2; //private MainWindow2 _mainWindow2; //private MainWindow3 _mainWindow3; //private MainWindow4 _mainWindow4; public ObservableCollection _records; // 添加静态集合来保持数据 //private static ObservableCollection _staticRecords = new ObservableCollection(); private static ObservableCollection _staticRecords = new ObservableCollection(); private static readonly string ReportFilePath = System.IO.Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "氧气自救器检验报表.csv"); Function ma; private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient; private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster; public ReportWindow2() { InitializeComponent(); _records = new ObservableCollection(); _records = _staticRecords; dataGrid.ItemsSource = _records; } // 添加新记录 public void AddRecord(string time, string date, double StartPress, double EndPress, double DiffPress, double ProtectTime,string no) { var record = new TestRecordForNegativePressure { Id = _records.Count + 1, Time = time, Date = date, DiffPress = DiffPress, EndPress = EndPress, ProtectTime = ProtectTime, StartPress = StartPress, CreateTime = DateTime.Now, No = no }; _records.Insert(0, record); // 新记录插入到最前面 SaveRecords(time, date, StartPress, EndPress, DiffPress, ProtectTime,no); } // 保存记录到文件 private void SaveRecords(string time, string date, double StartPress, double EndPress, double DiffPress, double ProtectTime,string no) { try { using (var connection = new MySqlConnection(DatabaseConfig.ConnectionString)) { connection.Open(); var sql = @"INSERT INTO test_recordsForNegativePressure (Time, Date,StartPress,EndPress,DiffPress,ProtectTime,No, CreateTime,Type) VALUES (@Time, @Date, @StartPress, @EndPress,@DiffPress,@ProtectTime,@No, @CreateTime,0)"; var record = new TestRecordForNegativePressure { Time = time, Date = date, DiffPress = DiffPress, EndPress = EndPress, ProtectTime = ProtectTime, StartPress = StartPress, CreateTime = DateTime.Now, No = no }; connection.Execute(sql, record); } } catch (Exception ex) { MessageBox.Show($"保存记录失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } private void BtnExport_Click(object sender, RoutedEventArgs e) { try { // 数据校验:无数据时提示 if (_records == null || _records.Count == 0) { MessageBox.Show("没有数据可导出", "提示", MessageBoxButton.OK, MessageBoxImage.Information); return; } // 保存文件对话框:后缀改为.xls,Excel可直接打开 var saveDialog = new Microsoft.Win32.SaveFileDialog { FileName = $"氧气自救器_负压检验报表_{DateTime.Now:yyyyMMdd_HHmmss}.xls", Filter = "Excel文件 (*.xls)|*.xls|所有文件 (*.*)|*.*", Title = "导出负压检验报表" }; if (saveDialog.ShowDialog() == true) { // 构建HTML表格(核心:通过CSS直接定义居中、列宽、样式) var htmlBuilder = new System.Text.StringBuilder(); htmlBuilder.AppendLine(""); // 表格整体样式:带边框、边框合并、统一字体 htmlBuilder.AppendLine(""); // 1. 表头行:居中+加粗+加宽列宽(重点优化日期、保压时间、记录时间) htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); // 加宽 htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); // 加宽 htmlBuilder.AppendLine(""); // 加宽 htmlBuilder.AppendLine(""); // 2. 数据行:居中对齐+数值格式化(保留2位小数) foreach (var record in _records) { htmlBuilder.AppendLine(""); // 每个单元格强制居中,添加内边距提升可读性 htmlBuilder.AppendLine($""); htmlBuilder.AppendLine($""); htmlBuilder.AppendLine($""); htmlBuilder.AppendLine($""); // 初始压力(2位小数) htmlBuilder.AppendLine($""); // 结束压力(2位小数) htmlBuilder.AppendLine($""); // 压差(2位小数) htmlBuilder.AppendLine($""); // 样品编号 htmlBuilder.AppendLine($""); // 保压时间(2位小数) htmlBuilder.AppendLine($""); // 记录时间 htmlBuilder.AppendLine(""); } // 闭合HTML标签 htmlBuilder.AppendLine("
编号日期时间初始压力结束压力压差样品编号保压时间记录时间
{record.Id.ToString() ?? ""}{record.Date?.ToString() ?? ""}{record.Time?.ToString() ?? ""}{record.StartPress:F2}{record.EndPress:F2}{record.DiffPress:F2}{record.No?.ToString() ?? ""}{record.ProtectTime:F2}{record.CreateTime:yyyy/MM/dd HH:mm:ss}
"); // 保存文件(UTF-8编码,避免中文乱码) System.IO.File.WriteAllText(saveDialog.FileName, htmlBuilder.ToString(), Encoding.UTF8); // 导出成功提示(明确格式已生效) MessageBox.Show( $"报表已成功导出到:\n{saveDialog.FileName}\n\n", "导出成功(格式已自动设置)", MessageBoxButton.OK, MessageBoxImage.Information); } } catch (Exception ex) { // 异常捕获与提示 MessageBox.Show($"导出失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } private void BtnClear_Click(object sender, RoutedEventArgs e) { var result = MessageBox.Show("确定要清空所有记录吗?此操作不可恢复!", "确认清空", MessageBoxButton.YesNo, MessageBoxImage.Warning); if (result == MessageBoxResult.Yes) { _records.Clear(); MessageBox.Show("记录已清空", "提示", MessageBoxButton.OK, MessageBoxImage.Information); } } private void Window_Loaded(object sender, RoutedEventArgs e) { string plcIp = "192.168.1.10"; bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502); if (!initSuccess) { MessageBox.Show("连接Modbus服务器失败!", "错误"); this.Close(); return; } // 检查连接状态 if (_tcpClient == null || !_tcpClient.Connected) { MessageBox.Show("Modbus连接异常!", "错误"); this.Close(); return; } ma = new Function(_modbusMaster); } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { // 停止ViewModel的定时器 if (DataContext is MainViewModel viewModel) { viewModel.StopTimer(); } // 释放Modbus资源 ModbusResourceManager.Instance?.Dispose(); // 延后到当前窗口完成关闭后再统一关停,避免关闭重入。 AppShutdownCoordinator.RequestShutdown(); } private void Window_Closed(object sender, EventArgs e) { // 由应用级关停统一处理其他窗口,避免关闭链路重入。 } //private void BtnClose_Click(object sender, RoutedEventArgs e) //{ // this.Close(); // 直接关闭当前窗口,不切换 //} private void BtnPrint_Click(object sender, RoutedEventArgs e) { ma.BtnClickFunctionForNew(Function.ButtonType.切换型, 15); } private bool TryReconnect() { try { string plcIp = "192.168.1.10"; bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502); if (initSuccess) { ma = new Function(_modbusMaster); return true; } } catch (Exception ex) { //ShowErrorMsg($"重新连接失败:{ex.Message}"); } return false; } private void SwitchWindow(ref T windowInstance, Func createFunc) where T : Window, new() { // 2. 检查资源是否可用(添加重连机制) if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null) { // 尝试重新连接 bool reconnectSuccess = TryReconnect(); if (!reconnectSuccess) { MessageBox.Show("TCP连接已断开,请重新连接!", "提示"); return; } } // 3. 复用窗口实例:不存在则创建,存在则激活 if (windowInstance == null) { windowInstance = createFunc(); // 添加窗口关闭事件处理 windowInstance.Closed += (s, args) => { WindowNavigationHelper.RestoreWindow(this); }; } else { WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance); return; } WindowNavigationHelper.ShowWithoutWhiteFlash(this, windowInstance); } private void BtnClose_Click(object sender, RoutedEventArgs e) { SwitchWindow(ref _mainWindow2, () => new MainWindow2()); } } }