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 partial class ReportWindow3 : Window { //private MainWindow _mainWindow; private MainWindow3 _mainWindow3; private ReportWindow3 _reportWindow3; //private MainWindow3 _mainWindow3; //private MainWindow4 _mainWindow4; public ObservableCollection _records; 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 ReportWindow3() { 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,1)"; 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; } var saveDialog = new Microsoft.Win32.SaveFileDialog { FileName = $"氧气自救器_正压检验报表_{DateTime.Now:yyyyMMdd_HHmmss}.xls", // 后缀改为xls,Excel直接打开 Filter = "Excel文件 (*.xls)|*.xls|所有文件 (*.*)|*.*" }; if (saveDialog.ShowDialog() == true) { // 用StringBuilder构建HTML表格(核心:直接定义居中+列宽样式) var htmlBuilder = new System.Text.StringBuilder(); htmlBuilder.AppendLine(""); // 表格整体样式:带边框、边框合并,避免杂乱 htmlBuilder.AppendLine(""); // 1. 表头行:居中+加粗+加宽列宽(按需调整width值) htmlBuilder.AppendLine(""); // 列宽设置(单位px,重点加宽日期、保压时间、记录时间列) 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 BtnClose_Click(object sender, RoutedEventArgs e) //{ // this.Close(); //} private void BtnPrint_Click(object sender, RoutedEventArgs e) { ma.BtnClickFunctionForNew(Function.ButtonType.切换型, 15); } 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(); // 确保应用程序完全退出 Application.Current.Shutdown(); } private void Window_Closed(object sender, EventArgs e) { //_mainWindow4?.Close(); _reportWindow3?.Close(); } //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) => { // 窗口关闭时重新启动定时器并显示当前窗口 this.Show(); this.Activate(); }; } else { // 激活已存在的窗口(前置显示) windowInstance.Activate(); return; } // 4. 切换窗口:隐藏当前窗口,显示目标窗口(非模态) this.Hide(); windowInstance.Show(); // 使用 Show() 而不是 ShowDialog() } private void BtnClose_Click(object sender, RoutedEventArgs e) { SwitchWindow(ref _mainWindow3, () => new MainWindow3()); } } }