Files
NonWovenFabric/WindowsFormsApp6/Form2.cs
GukSang.Jin f00d3dd4dd '初始化'
2025-12-31 09:43:35 +08:00

696 lines
27 KiB
C#
Raw 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 System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel; // 用于 .xlsx
using NPOI.HSSF.UserModel; // 用于 .xls
using NPOI.SS.Util;
// 使用别名解决命名空间冲突
using NPOIBorderStyle = NPOI.SS.UserModel.BorderStyle;
using NPOIHorizontalAlignment = NPOI.SS.UserModel.HorizontalAlignment;
namespace WindowsFormsApp6
{
public partial class Form2 : Form
{
private System.Windows.Forms.Timer dataTimer;
private DataTable sampleDataTable;
private int sampleCount = 0;
public Form2()
{
InitializeComponent();
InitializeDataTable();
InitializeTimer();
InitializeDataGridView();
InitializeEventHandlers();
}
/// <summary>
/// 初始化 DataGridView 列
/// </summary>
private void InitializeDataGridView()
{
// 清除现有列
dataGridView1.Columns.Clear();
// 添加新列以匹配 Excel 表格结构
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
Name = "序号",
HeaderText = "序号",
DataPropertyName = "序号",
Width = 150,
ReadOnly = true,
DefaultCellStyle = new DataGridViewCellStyle { Alignment = DataGridViewContentAlignment.MiddleCenter }
});
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
Name = "试样1",
HeaderText = "试样1",
DataPropertyName = "试样1",
Width = 150,
ReadOnly = true,
DefaultCellStyle = new DataGridViewCellStyle
{
Alignment = DataGridViewContentAlignment.MiddleCenter,
BackColor = Color.FromArgb(255, 255, 200) // 黄色背景
}
});
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
Name = "试样2",
HeaderText = "试样2",
DataPropertyName = "试样2",
Width = 150,
ReadOnly = true,
DefaultCellStyle = new DataGridViewCellStyle
{
Alignment = DataGridViewContentAlignment.MiddleCenter,
BackColor = Color.FromArgb(255, 255, 200)
}
});
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
Name = "试样3",
HeaderText = "试样3",
DataPropertyName = "试样3",
Width = 150,
ReadOnly = true,
DefaultCellStyle = new DataGridViewCellStyle
{
Alignment = DataGridViewContentAlignment.MiddleCenter,
BackColor = Color.FromArgb(255, 255, 200)
}
});
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
Name = "试样4",
HeaderText = "试样4",
DataPropertyName = "试样4",
Width = 150,
ReadOnly = true,
DefaultCellStyle = new DataGridViewCellStyle
{
Alignment = DataGridViewContentAlignment.MiddleCenter,
BackColor = Color.FromArgb(255, 255, 200)
}
});
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
Name = "试样5",
HeaderText = "试样5",
DataPropertyName = "试样5",
Width = 150,
ReadOnly = true,
DefaultCellStyle = new DataGridViewCellStyle
{
Alignment = DataGridViewContentAlignment.MiddleCenter,
BackColor = Color.FromArgb(255, 255, 200)
}
});
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
Name = "时间",
HeaderText = "时间",
DataPropertyName = "时间",
Width = 200,
ReadOnly = true,
DefaultCellStyle = new DataGridViewCellStyle { Alignment = DataGridViewContentAlignment.MiddleCenter }
});
// 绑定数据源
dataGridView1.DataSource = sampleDataTable;
// 添加单元格格式化事件
dataGridView1.CellFormatting += DataGridView1_CellFormatting;
}
/// <summary>
/// 单元格格式化事件 - 处理平均值行的显示
/// </summary>
private void DataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (dataGridView1.Columns[e.ColumnIndex].Name == "时间" && e.RowIndex >= 0)
{
DataGridViewRow row = dataGridView1.Rows[e.RowIndex];
if (row.Cells["序号"].Value != null && row.Cells["序号"].Value.ToString() == "平均时间(s)")
{
// 计算总平均值并显示
if (row.Cells["试样1"].Value != null)
{
double avg1 = Convert.ToDouble(row.Cells["试样1"].Value);
double avg2 = Convert.ToDouble(row.Cells["试样2"].Value);
double avg3 = Convert.ToDouble(row.Cells["试样3"].Value);
double avg4 = Convert.ToDouble(row.Cells["试样4"].Value);
double avg5 = Convert.ToDouble(row.Cells["试样5"].Value);
double overallAvg = (avg1 + avg2 + avg3 + avg4 + avg5) / 5;
e.Value = overallAvg.ToString("F2");
e.FormattingApplied = true;
}
}
else if (e.Value != null && e.Value != DBNull.Value)
{
// 正常时间格式化
DateTime dt = Convert.ToDateTime(e.Value);
e.Value = dt.ToString("yyyy-MM-dd HH:mm:ss");
e.FormattingApplied = true;
}
}
}
/// <summary>
/// 初始化事件处理器
/// </summary>
private void InitializeEventHandlers()
{
// 连接设备按钮
button1.Click += Button1_Click;
// 打印按钮
button2.Click += Button2_Click;
// 导出按钮
button3.Click += Button3_Click;
// 返回按钮
button4.Click += Button4_Click;
// 生成模拟数据按钮
button5.Click += Button5_Click;
// 更新日期时间标签
System.Windows.Forms.Timer clockTimer = new System.Windows.Forms.Timer();
clockTimer.Interval = 1000;
clockTimer.Tick += (s, e) => label2.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
clockTimer.Start();
}
/// <summary>
/// 连接设备按钮点击事件
/// </summary>
private void Button1_Click(object sender, EventArgs e)
{
if (dataTimer.Enabled)
{
StopDataCollection();
button1.Text = "🔗 连接设备";
button1.BackColor = Color.FromArgb(46, 204, 113);
MessageBox.Show("已停止数据采集", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
StartDataCollection();
button1.Text = "⏸️ 停止采集";
button1.BackColor = Color.FromArgb(231, 76, 60);
MessageBox.Show("开始数据采集", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
/// <summary>
/// 打印按钮点击事件
/// </summary>
private void Button2_Click(object sender, EventArgs e)
{
MessageBox.Show("打印功能开发中...", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
/// <summary>
/// 导出按钮点击事件
/// </summary>
private void Button3_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog
{
Filter = "Excel 文件 (*.xlsx)|*.xlsx|Excel 97-2003 (*.xls)|*.xls",
FileName = $"液体吸收测试报告_{DateTime.Now:yyyyMMdd_HHmmss}",
Title = "导出数据"
};
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
GenerateReport(saveFileDialog.FileName);
}
}
/// <summary>
/// 返回按钮点击事件
/// </summary>
private void Button4_Click(object sender, EventArgs e)
{
this.Close();
}
/// <summary>
/// 生成模拟数据按钮点击事件
/// </summary>
private void Button5_Click(object sender, EventArgs e)
{
GenerateMockData();
}
/// <summary>
/// 初始化数据表结构
/// </summary>
private void InitializeDataTable()
{
sampleDataTable = new DataTable();
sampleDataTable.Columns.Add("序号", typeof(string));
sampleDataTable.Columns.Add("试样1", typeof(double));
sampleDataTable.Columns.Add("试样2", typeof(double));
sampleDataTable.Columns.Add("试样3", typeof(double));
sampleDataTable.Columns.Add("试样4", typeof(double));
sampleDataTable.Columns.Add("试样5", typeof(double));
sampleDataTable.Columns.Add("时间", typeof(DateTime));
}
/// <summary>
/// 初始化定时器用于模拟寄存器数据读取
/// </summary>
private void InitializeTimer()
{
dataTimer = new System.Windows.Forms.Timer();
dataTimer.Interval = 1000; // 每秒读取一次
dataTimer.Tick += DataTimer_Tick;
}
/// <summary>
/// 定时器事件 - 模拟从寄存器读取数据
/// </summary>
private void DataTimer_Tick(object sender, EventArgs e)
{
// 移除旧的平均值行(如果存在)
DataRow[] avgRows = sampleDataTable.Select("序号 = '平均时间(s)'");
foreach (DataRow avgRow in avgRows)
{
sampleDataTable.Rows.Remove(avgRow);
}
// 模拟从寄存器读取数据(实际应用中替换为真实的寄存器读取代码)
double sample1 = ReadRegisterData(0); // 寄存器地址 0
double sample2 = ReadRegisterData(1); // 寄存器地址 1
double sample3 = ReadRegisterData(2); // 寄存器地址 2
double sample4 = ReadRegisterData(3); // 寄存器地址 3
double sample5 = ReadRegisterData(4); // 寄存器地址 4
// 添加到数据表
sampleCount++;
DataRow dataRow = sampleDataTable.NewRow();
dataRow["序号"] = $"时间(s)";
dataRow["试样1"] = sample1;
dataRow["试样2"] = sample2;
dataRow["试样3"] = sample3;
dataRow["试样4"] = sample4;
dataRow["试样5"] = sample5;
dataRow["时间"] = DateTime.Now;
sampleDataTable.Rows.Add(dataRow);
// 更新界面显示
UpdateDisplay();
}
/// <summary>
/// 模拟从寄存器读取数据
/// 实际应用中替换为真实的 Modbus 或其他协议读取
/// </summary>
private double ReadRegisterData(int registerAddress)
{
// 模拟数据30-34 之间的随机值
Random random = new Random(Guid.NewGuid().GetHashCode());
return 30 + random.NextDouble() * 4;
}
/// <summary>
/// 生成模拟测试数据
/// </summary>
public void GenerateMockData()
{
// 清空现有数据
sampleDataTable.Clear();
sampleCount = 0;
// 生成10条模拟数据
Random random = new Random();
DateTime startTime = DateTime.Now.AddMinutes(-10);
for (int i = 0; i < 10; i++)
{
DataRow dataRow = sampleDataTable.NewRow();
dataRow["序号"] = "时间(s)";
// 为每个试样生成模拟数据30-34之间的随机值带小数点
dataRow["试样1"] = Math.Round(30 + random.NextDouble() * 4, 2);
dataRow["试样2"] = Math.Round(30 + random.NextDouble() * 4, 2);
dataRow["试样3"] = Math.Round(30 + random.NextDouble() * 4, 2);
dataRow["试样4"] = Math.Round(30 + random.NextDouble() * 4, 2);
dataRow["试样5"] = Math.Round(30 + random.NextDouble() * 4, 2);
// 时间递增
dataRow["时间"] = startTime.AddMinutes(i);
sampleDataTable.Rows.Add(dataRow);
sampleCount++;
}
// 更新显示(包括平均值)
UpdateDisplay();
MessageBox.Show($"已生成 {sampleCount} 条模拟数据", "模拟数据生成", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
/// <summary>
/// 更新界面显示
/// </summary>
private void UpdateDisplay()
{
// 刷新 DataGridView
if (dataGridView1.DataSource != null)
{
((DataTable)dataGridView1.DataSource).AcceptChanges();
dataGridView1.Refresh();
}
// 计算平均时间并显示
if (sampleDataTable.Rows.Count > 0)
{
double avgSample1 = sampleDataTable.AsEnumerable().Average(r => r.Field<double>("试样1"));
double avgSample2 = sampleDataTable.AsEnumerable().Average(r => r.Field<double>("试样2"));
double avgSample3 = sampleDataTable.AsEnumerable().Average(r => r.Field<double>("试样3"));
double avgSample4 = sampleDataTable.AsEnumerable().Average(r => r.Field<double>("试样4"));
double avgSample5 = sampleDataTable.AsEnumerable().Average(r => r.Field<double>("试样5"));
double overallAvg = (avgSample1 + avgSample2 + avgSample3 + avgSample4 + avgSample5) / 5;
// 添加平均值行到表格底部(如果还没有)
DataRow[] avgRows = sampleDataTable.Select("序号 = '平均时间(s)'");
if (avgRows.Length == 0)
{
DataRow avgRow = sampleDataTable.NewRow();
avgRow["序号"] = "平均时间(s)";
avgRow["试样1"] = avgSample1;
avgRow["试样2"] = avgSample2;
avgRow["试样3"] = avgSample3;
avgRow["试样4"] = avgSample4;
avgRow["试样5"] = avgSample5;
// avgRow["时间"] = $"({overallAvg:F2}) 系统计算";
sampleDataTable.Rows.Add(avgRow);
}
else
{
// 更新现有平均值行
avgRows[0]["试样1"] = avgSample1;
avgRows[0]["试样2"] = avgSample2;
avgRows[0]["试样3"] = avgSample3;
avgRows[0]["试样4"] = avgSample4;
avgRows[0]["试样5"] = avgSample5;
// avgRows[0]["时间"] = $"({overallAvg:F2}) 系统计算";
}
}
}
/// <summary>
/// 启动数据采集
/// </summary>
public void StartDataCollection()
{
dataTimer.Start();
}
/// <summary>
/// 停止数据采集
/// </summary>
public void StopDataCollection()
{
dataTimer.Stop();
}
/// <summary>
/// 导出数据到 Excel (.xlsx)
/// </summary>
public void ExportToExcel(string filePath)
{
try
{
IWorkbook workbook;
// 根据文件扩展名选择格式
if (filePath.EndsWith(".xlsx"))
{
workbook = new XSSFWorkbook(); // Excel 2007+
}
else
{
workbook = new HSSFWorkbook(); // Excel 97-2003
}
ISheet sheet = workbook.CreateSheet("液体吸收测试报表");
// 创建标题行
IRow headerRow = sheet.CreateRow(0);
headerRow.CreateCell(0).SetCellValue("序号");
headerRow.CreateCell(1).SetCellValue("试样1");
headerRow.CreateCell(2).SetCellValue("试样2");
headerRow.CreateCell(3).SetCellValue("试样3");
headerRow.CreateCell(4).SetCellValue("试样4");
headerRow.CreateCell(5).SetCellValue("试样5");
headerRow.CreateCell(6).SetCellValue("时间");
// 设置标题行样式
ICellStyle headerStyle = workbook.CreateCellStyle();
headerStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Yellow.Index;
headerStyle.FillPattern = FillPattern.SolidForeground;
IFont headerFont = workbook.CreateFont();
headerFont.IsBold = true;
headerStyle.SetFont(headerFont);
for (int i = 0; i < 7; i++)
{
headerRow.GetCell(i).CellStyle = headerStyle;
}
// 填充数据
int rowIndex = 1;
foreach (DataRow dataRow in sampleDataTable.Rows)
{
// 跳过平均值行
if (dataRow["序号"].ToString() == "平均时间(s)")
continue;
IRow row = sheet.CreateRow(rowIndex);
row.CreateCell(0).SetCellValue(dataRow["序号"].ToString());
row.CreateCell(1).SetCellValue(Convert.ToDouble(dataRow["试样1"]));
row.CreateCell(2).SetCellValue(Convert.ToDouble(dataRow["试样2"]));
row.CreateCell(3).SetCellValue(Convert.ToDouble(dataRow["试样3"]));
row.CreateCell(4).SetCellValue(Convert.ToDouble(dataRow["试样4"]));
row.CreateCell(5).SetCellValue(Convert.ToDouble(dataRow["试样5"]));
// 处理时间列
if (dataRow["时间"] != DBNull.Value)
{
row.CreateCell(6).SetCellValue(Convert.ToDateTime(dataRow["时间"]).ToString("yyyy-MM-dd HH:mm:ss"));
}
rowIndex++;
}
// 添加平均值行
IRow avgRow = sheet.CreateRow(rowIndex);
avgRow.CreateCell(0).SetCellValue("平均时间(s)");
// 计算平均值(排除平均值行)
var dataRows = sampleDataTable.AsEnumerable().Where(r => r.Field<string>("序号") != "平均时间(s)");
double avgSample1 = dataRows.Average(r => r.Field<double>("试样1"));
double avgSample2 = dataRows.Average(r => r.Field<double>("试样2"));
double avgSample3 = dataRows.Average(r => r.Field<double>("试样3"));
double avgSample4 = dataRows.Average(r => r.Field<double>("试样4"));
double avgSample5 = dataRows.Average(r => r.Field<double>("试样5"));
double overallAvg = (avgSample1 + avgSample2 + avgSample3 + avgSample4 + avgSample5) / 5;
avgRow.CreateCell(1).SetCellValue(avgSample1);
avgRow.CreateCell(2).SetCellValue(avgSample2);
avgRow.CreateCell(3).SetCellValue(avgSample3);
avgRow.CreateCell(4).SetCellValue(avgSample4);
avgRow.CreateCell(5).SetCellValue(avgSample5);
// 显示总平均值
ICell avgCell = avgRow.CreateCell(6);
avgCell.SetCellValue(overallAvg.ToString("F2"));
// 设置平均值行样式
ICellStyle avgStyle = workbook.CreateCellStyle();
avgStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Yellow.Index;
avgStyle.FillPattern = FillPattern.SolidForeground;
for (int i = 0; i < 7; i++)
{
if (avgRow.GetCell(i) != null)
{
avgRow.GetCell(i).CellStyle = avgStyle;
}
}
// 自动调整列宽
for (int i = 0; i < 7; i++)
{
sheet.AutoSizeColumn(i);
}
// 保存文件
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
workbook.Write(fs);
}
MessageBox.Show($"数据已成功导出到:{filePath}", "导出成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"导出失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 生成报表(带格式的 Excel
/// </summary>
public void GenerateReport(string filePath)
{
try
{
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("液体吸收测试报表");
// 创建样式
ICellStyle titleStyle = workbook.CreateCellStyle();
IFont titleFont = workbook.CreateFont();
titleFont.FontHeightInPoints = 16;
titleFont.IsBold = true;
titleStyle.SetFont(titleFont);
titleStyle.Alignment = NPOIHorizontalAlignment.Center;
ICellStyle headerStyle = workbook.CreateCellStyle();
headerStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Yellow.Index;
headerStyle.FillPattern = FillPattern.SolidForeground;
headerStyle.BorderBottom = NPOIBorderStyle.Thin;
headerStyle.BorderTop = NPOIBorderStyle.Thin;
headerStyle.BorderLeft = NPOIBorderStyle.Thin;
headerStyle.BorderRight = NPOIBorderStyle.Thin;
IFont headerFont = workbook.CreateFont();
headerFont.IsBold = true;
headerStyle.SetFont(headerFont);
headerStyle.Alignment = NPOIHorizontalAlignment.Center;
ICellStyle dataStyle = workbook.CreateCellStyle();
dataStyle.BorderBottom = NPOIBorderStyle.Thin;
dataStyle.BorderTop = NPOIBorderStyle.Thin;
dataStyle.BorderLeft = NPOIBorderStyle.Thin;
dataStyle.BorderRight = NPOIBorderStyle.Thin;
dataStyle.Alignment = NPOIHorizontalAlignment.Center;
// 标题
IRow titleRow = sheet.CreateRow(0);
ICell titleCell = titleRow.CreateCell(0);
titleCell.SetCellValue("液体吸收测试报表");
titleCell.CellStyle = titleStyle;
sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, 6));
// 表头
IRow headerRow = sheet.CreateRow(2);
string[] headers = { "序号", "试样1", "试样2", "试样3", "试样4", "试样5", "根据标准" };
for (int i = 0; i < headers.Length; i++)
{
ICell cell = headerRow.CreateCell(i);
cell.SetCellValue(headers[i]);
cell.CellStyle = headerStyle;
}
// 数据行
int rowIndex = 3;
IRow timeRow = sheet.CreateRow(rowIndex++);
timeRow.CreateCell(0).SetCellValue("时间(s)");
timeRow.GetCell(0).CellStyle = dataStyle;
for (int i = 1; i <= 5; i++)
{
double value = 29 + i; // 示例数据30, 31, 32, 33, 34
ICell cell = timeRow.CreateCell(i);
cell.SetCellValue(value);
cell.CellStyle = dataStyle;
// 黄色背景
ICellStyle yellowStyle = workbook.CreateCellStyle();
yellowStyle.CloneStyleFrom(dataStyle);
yellowStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Yellow.Index;
yellowStyle.FillPattern = FillPattern.SolidForeground;
cell.CellStyle = yellowStyle;
}
ICell standardCell = timeRow.CreateCell(6);
standardCell.CellStyle = dataStyle;
// 平均时间行
IRow avgRow = sheet.CreateRow(rowIndex);
avgRow.CreateCell(0).SetCellValue("平均时间(s)");
avgRow.GetCell(0).CellStyle = dataStyle;
ICell avgCell = avgRow.CreateCell(1);
avgCell.SetCellValue("32");
avgCell.CellStyle = dataStyle;
// 黄色背景
ICellStyle avgYellowStyle = workbook.CreateCellStyle();
avgYellowStyle.CloneStyleFrom(dataStyle);
avgYellowStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Yellow.Index;
avgYellowStyle.FillPattern = FillPattern.SolidForeground;
avgCell.CellStyle = avgYellowStyle;
sheet.AddMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 1, 5));
// 设置列宽
sheet.SetColumnWidth(0, 20 * 256);
for (int i = 1; i <= 6; i++)
{
sheet.SetColumnWidth(i, 15 * 256);
}
// 保存文件
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
workbook.Write(fs);
}
MessageBox.Show($"报表已成功生成:{filePath}", "生成成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"生成报表失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 清空数据
/// </summary>
public void ClearData()
{
sampleDataTable.Clear();
sampleCount = 0;
UpdateDisplay();
}
}
}