696 lines
27 KiB
C#
696 lines
27 KiB
C#
|
|
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 Form1 : Form
|
|||
|
|
{
|
|||
|
|
private System.Windows.Forms.Timer dataTimer;
|
|||
|
|
private DataTable sampleDataTable;
|
|||
|
|
private int sampleCount = 0;
|
|||
|
|
|
|||
|
|
public Form1()
|
|||
|
|
{
|
|||
|
|
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 < 1; 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();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|