Files
zijiuqizonghejianyanyi/ReportWindow4.xaml.cs
2026-03-16 15:36:54 +08:00

422 lines
17 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<TestRecord> _records;
// 添加静态集合来保持数据
private static ObservableCollection<TestRecord> _staticRecords = new ObservableCollection<TestRecord>();
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<TestRecord>();
_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", // 后缀设为xlsExcel直接打开
Filter = "Excel文件 (*.xls)|*.xls|所有文件 (*.*)|*.*"
};
if (saveDialog.ShowDialog() == true)
{
// 构建HTML表格核心直接定义样式Excel能识别
var htmlBuilder = new System.Text.StringBuilder();
// HTML头部设置表格整体样式
htmlBuilder.AppendLine("<html><body>");
// 表格样式:边框+居中,列宽直接定义(单位:像素)
htmlBuilder.AppendLine("<table border='1' style='border-collapse:collapse;'>");
// 1. 表头行:居中+加粗+指定列宽
htmlBuilder.AppendLine("<tr style='background-color:#f0f0f0;'>");
// 编号120px、日期180px加宽、时间100px、压力180px、样品编号120px、测试时长160px加宽、记录时间220px
htmlBuilder.AppendLine("<th style='width:120px;text-align:center;font-weight:bold;padding:5px;'>编号</th>");
htmlBuilder.AppendLine("<th style='width:180px;text-align:center;font-weight:bold;padding:5px;'>日期</th>");
htmlBuilder.AppendLine("<th style='width:100px;text-align:center;font-weight:bold;padding:5px;'>时间</th>");
htmlBuilder.AppendLine("<th style='width:180px;text-align:center;font-weight:bold;padding:5px;'>排气阀开启压力pa</th>");
htmlBuilder.AppendLine("<th style='width:120px;text-align:center;font-weight:bold;padding:5px;'>样品编号</th>");
htmlBuilder.AppendLine("<th style='width:160px;text-align:center;font-weight:bold;padding:5px;'>测试时长</th>");
htmlBuilder.AppendLine("<th style='width:220px;text-align:center;font-weight:bold;padding:5px;'>记录时间</th>");
htmlBuilder.AppendLine("</tr>");
// 2. 数据行:居中+与表头列宽对应
foreach (var record in _records)
{
htmlBuilder.AppendLine("<tr>");
// 每个单元格设置居中对齐,继承列宽
htmlBuilder.AppendLine($"<td style='text-align:center;padding:5px;'>{record.Id.ToString() ?? ""}</td>");
htmlBuilder.AppendLine($"<td style='text-align:center;padding:5px;'>{record.Date?.ToString() ?? ""}</td>");
htmlBuilder.AppendLine($"<td style='text-align:center;padding:5px;'>{record.Time?.ToString() ?? ""}</td>");
htmlBuilder.AppendLine($"<td style='text-align:center;padding:5px;'>{record.FlowRate:F2}</td>"); // 保留2位小数
htmlBuilder.AppendLine($"<td style='text-align:center;padding:5px;'>{record.No?.ToString() ?? ""}</td>");
htmlBuilder.AppendLine($"<td style='text-align:center;padding:5px;'>{record.Duration?.ToString() ?? ""}</td>");
htmlBuilder.AppendLine($"<td style='text-align:center;padding:5px;'>{record.CreateTime:yyyy/MM/dd HH:mm:ss}</td>");
htmlBuilder.AppendLine("</tr>");
}
// 闭合HTML标签
htmlBuilder.AppendLine("</table></body></html>");
// 保存为HTML格式文件后缀.xlsExcel可直接打开
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<T>(ref T windowInstance, Func<T> 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());
}
}
}