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; using System.Windows.Media; using System.Windows.Media.Animation; namespace 自救器呼吸器综合检验仪 { public partial class ReportWindow4 : Window { //private MainWindow _mainWindow; //private MainWindow2 _mainWindow2; //private MainWindow3 _mainWindow3; private MainWindow4 _mainWindow4; private ReportWindow4 _reportWindow4; 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 ReportWindow4() { InitializeComponent(); _records = new ObservableCollection(); _records = _staticRecords; dataGrid.ItemsSource = _records; } // 添加新记录 public void AddRecord(string time, string date, double flowRate, string duration, string No) { var record = new TestRecord { Id = _records.Count + 1, Time = time, Date = date, FlowRate = flowRate, Duration = duration, CreateTime = DateTime.Now, No = No }; _records.Insert(0, record); // 新记录插入到最前面 SaveRecords(time, date, flowRate, duration, No); } // 保存记录到文件 private void SaveRecords(string time, string date, double flowRate, string duration, string No) { try { using (var connection = new MySqlConnection(DatabaseConfig.ConnectionString)) { connection.Open(); var sql = @"INSERT INTO test_records (Time, Date, FlowRate, Duration,No, CreateTime,Type) VALUES (@Time, @Date, @FlowRate, @Duration,@No, @CreateTime,1)"; var record = new TestRecord { Time = time, Date = date, FlowRate = flowRate, Duration = duration, 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}.csv", // Filter = "CSV文件 (*.csv)|*.csv" // }; // if (saveDialog.ShowDialog() == true) // { // // 从_records直接生成CSV文件 // using (var writer = new StreamWriter(saveDialog.FileName, false, Encoding.UTF8)) // { // // 写入表头 // writer.WriteLine("编号,日期,时间,排气阀开启压力pa,样品编号,测试时长,记录时间"); // // 写入数据 // foreach (var record in _records) // { // writer.WriteLine($"{record.Id},{record.Date},{record.Time},{record.FlowRate:F2},{record.No},{record.Duration},{record.CreateTime:yyyy/MM/dd HH:mm:ss}"); // } // } // MessageBox.Show($"报表已导出到:{saveDialog.FileName}", "导出成功", // MessageBoxButton.OK, MessageBoxImage.Information); // } // } // 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) { // 构建HTML表格(核心:直接定义样式,Excel能识别) var htmlBuilder = new System.Text.StringBuilder(); // HTML头部:设置表格整体样式 htmlBuilder.AppendLine(""); // 表格样式:边框+居中,列宽直接定义(单位:像素) htmlBuilder.AppendLine(""); // 1. 表头行:居中+加粗+指定列宽 htmlBuilder.AppendLine(""); // 编号(120px)、日期(180px,加宽)、时间(100px)、压力(180px)、样品编号(120px)、测试时长(160px,加宽)、记录时间(220px) htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); htmlBuilder.AppendLine(""); // 2. 数据行:居中+与表头列宽对应 foreach (var record in _records) { htmlBuilder.AppendLine(""); // 每个单元格设置居中对齐,继承列宽 htmlBuilder.AppendLine($""); htmlBuilder.AppendLine($""); htmlBuilder.AppendLine($""); htmlBuilder.AppendLine($""); // 保留2位小数 htmlBuilder.AppendLine($""); htmlBuilder.AppendLine($""); htmlBuilder.AppendLine($""); htmlBuilder.AppendLine(""); } // 闭合HTML标签 htmlBuilder.AppendLine("
编号日期时间排气阀开启压力pa样品编号测试时长记录时间
{record.Id.ToString() ?? ""}{record.Date?.ToString() ?? ""}{record.Time?.ToString() ?? ""}{record.FlowRate:F2}{record.No?.ToString() ?? ""}{record.Duration?.ToString() ?? ""}{record.CreateTime:yyyy/MM/dd HH:mm:ss}
"); // 保存为HTML格式文件(后缀.xls,Excel可直接打开) 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 Window_Loaded(object sender, RoutedEventArgs e) //{ //} private void BtnPrint_Click(object sender, RoutedEventArgs e) { // 判断是否有数据可打印 if (_records == null || _records.Count == 0) { MessageBox.Show("当前没有可打印的数据。", "提示", MessageBoxButton.OK, MessageBoxImage.Information); return; } 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(); _reportWindow4?.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() { if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null) { if (!TryReconnect()) { MessageBox.Show("TCP连接已断开,请重新连接!", "提示"); return; } } Window overlay = null; try { overlay = new Window { Owner = this, WindowStyle = WindowStyle.None, AllowsTransparency = true, Background = System.Windows.Media.Brushes.Transparent, ShowInTaskbar = false, ResizeMode = ResizeMode.NoResize, Width = this.ActualWidth, Height = this.ActualHeight, Left = this.Left, Top = this.Top, ShowActivated = false, Topmost = true }; var grid = new Grid(); var tb = new TextBlock { Text = "正在加载,请稍候...", Foreground = System.Windows.Media.Brushes.Black, Background = System.Windows.Media.Brushes.Transparent, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Bottom, Margin = new Thickness(0, 0, 0, 20), FontSize = 16 }; grid.Children.Add(tb); overlay.Content = grid; overlay.Show(); void ShowTargetWindow(T target) { if (target.IsVisible) { target.Activate(); this.Hide(); overlay?.Close(); return; } target.Opacity = 0; void OnContentRendered(object s, EventArgs e) { target.ContentRendered -= OnContentRendered; var anim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200)); target.BeginAnimation(Window.OpacityProperty, anim); this.Hide(); target.Activate(); overlay?.Close(); } target.ContentRendered += OnContentRendered; target.Show(); } if (windowInstance == null) { windowInstance = createFunc(); windowInstance.Closed += (s, args) => { this.Show(); this.Activate(); }; ShowTargetWindow(windowInstance); } else { ShowTargetWindow(windowInstance); } } catch (Exception ex) { overlay?.Close(); MessageBox.Show($"切换窗口失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } private void BtnClose_Click(object sender, RoutedEventArgs e) { SwitchWindow(ref _mainWindow4, () => new MainWindow4()); } } }