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
{
#region 常量定义
private const int TIMER_INTERVAL = 1000;
private const double MIN_WEIGHT = 10.0;
private const double MAX_WEIGHT = 20.0;
private const string DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
private const string ROW_INITIAL_WEIGHT = "初始重量(g)";
private const string ROW_AFTER_WEIGHT = "浸润后重量(g)";
private const string ROW_ABSORPTION = "液体吸收量(%)";
private const string ROW_SOAK_TIME = "浸润时间";
private const string ROW_HANG_TIME = "悬挂时间";
private const string ROW_RUN_SPEED = "运行速度";
private const string ROW_AVG_ABSORPTION = "液体吸收量平均值(%)";
private const string ROW_MAX_ABSORPTION = "液体吸收量最大值(%)";
private const string ROW_STD_DEVIATION = "标准偏差";
#endregion
#region 字段
private System.Windows.Forms.Timer dataTimer;
private System.Windows.Forms.Timer clockTimer;
private DataTable sampleDataTable;
private int sampleCount = 0;
private int currentSampleCount = 5; // 当前试样数量,可动态调整
private readonly Random random = new Random();
#endregion
public Form2()
{
InitializeComponent();
InitializeDataTable();
InitializeTimer();
InitializeDataGridView();
InitializeEventHandlers();
}
///
/// 初始化 DataGridView 列
///
private void InitializeDataGridView()
{
dataGridView1.SuspendLayout();
try
{
dataGridView1.Columns.Clear();
// 创建共享样式
var centerStyle = new DataGridViewCellStyle
{
Alignment = DataGridViewContentAlignment.MiddleCenter
};
var yellowCenterStyle = new DataGridViewCellStyle
{
Alignment = DataGridViewContentAlignment.MiddleCenter,
BackColor = Color.FromArgb(255, 255, 200)
};
// 添加序号列
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
Name = "序号",
HeaderText = "序号",
DataPropertyName = "序号",
Width = 180,
ReadOnly = true,
DefaultCellStyle = centerStyle
});
// 根据当前试样数量动态添加列
for (int i = 1; i <= currentSampleCount; i++)
{
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
Name = $"试样{i}",
HeaderText = $"试样{i}",
DataPropertyName = $"试样{i}",
Width = 150,
ReadOnly = true,
DefaultCellStyle = yellowCenterStyle
});
}
// 绑定数据源
dataGridView1.DataSource = sampleDataTable;
dataGridView1.CellFormatting += DataGridView1_CellFormatting;
}
finally
{
dataGridView1.ResumeLayout();
}
}
///
/// 单元格格式化事件
///
private void DataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.RowIndex < 0) return;
// 格式化数值显示为2位小数
if (e.Value != null && e.Value != DBNull.Value)
{
if (double.TryParse(e.Value.ToString(), out double numValue))
{
e.Value = numValue.ToString("F2");
e.FormattingApplied = true;
}
}
}
///
/// 初始化事件处理器
///
private void InitializeEventHandlers()
{
button1.Click += Button1_Click;
button2.Click += Button2_Click;
button3.Click += Button3_Click;
button4.Click += Button4_Click;
button5.Click += Button5_Click;
clockTimer = new System.Windows.Forms.Timer
{
Interval = TIMER_INTERVAL
};
clockTimer.Tick += (s, e) => label2.Text = DateTime.Now.ToString(DATE_TIME_FORMAT);
clockTimer.Start();
}
///
/// 连接设备按钮点击事件
///
private void Button1_Click(object sender, EventArgs e)
{
if (dataTimer.Enabled)
{
StopDataCollection();
UpdateButtonState(button1, "🔗 连接设备", Color.FromArgb(46, 204, 113));
ShowMessage("已停止数据采集");
}
else
{
StartDataCollection();
UpdateButtonState(button1, "⏸️ 停止采集", Color.FromArgb(231, 76, 60));
ShowMessage("开始数据采集");
}
}
///
/// 打印按钮点击事件
///
private void Button2_Click(object sender, EventArgs e)
{
ShowMessage("打印功能开发中...");
}
///
/// 更新按钮状态
///
private void UpdateButtonState(Button button, string text, Color backColor)
{
button.Text = text;
button.BackColor = backColor;
}
///
/// 显示提示消息
///
private void ShowMessage(string message, string title = "提示", MessageBoxIcon icon = MessageBoxIcon.Information)
{
MessageBox.Show(message, title, MessageBoxButtons.OK, icon);
}
///
/// 导出按钮点击事件
///
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);
}
}
///
/// 返回按钮点击事件
///
private void Button4_Click(object sender, EventArgs e)
{
this.Close();
}
///
/// 生成模拟数据按钮点击事件
///
private void Button5_Click(object sender, EventArgs e)
{
GenerateMockData();
}
///
/// 初始化数据表结构
///
private void InitializeDataTable()
{
sampleDataTable = new DataTable();
sampleDataTable.Columns.Add("序号", typeof(string));
// 根据当前试样数量动态添加列
for (int i = 1; i <= currentSampleCount; i++)
{
sampleDataTable.Columns.Add($"试样{i}", typeof(object));
}
}
///
/// 设置试样数量并重新初始化
///
public void SetSampleCount(int count)
{
if (count < 1 || count > 20) // 限制最大20个试样
{
ShowMessage("试样数量必须在1-20之间", "参数错误", MessageBoxIcon.Warning);
return;
}
currentSampleCount = count;
InitializeDataTable();
InitializeDataGridView();
}
///
/// 初始化定时器用于模拟寄存器数据读取
///
private void InitializeTimer()
{
dataTimer = new System.Windows.Forms.Timer
{
Interval = TIMER_INTERVAL
};
dataTimer.Tick += DataTimer_Tick;
}
///
/// 定时器事件 - 模拟从寄存器读取数据
///
private void DataTimer_Tick(object sender, EventArgs e)
{
// 清除旧的计算行
RemoveCalculatedRows();
// 读取初始重量和浸润后重量
double[] initialWeights = new double[currentSampleCount];
double[] afterWeights = new double[currentSampleCount];
for (int i = 0; i < currentSampleCount; i++)
{
initialWeights[i] = ReadRegisterData(i * 2); // 初始重量
afterWeights[i] = ReadRegisterData(i * 2 + 1); // 浸润后重量
}
sampleCount++;
// 更新显示
UpdateDisplay(initialWeights, afterWeights);
}
///
/// 移除计算行
///
private void RemoveCalculatedRows()
{
var rowsToRemove = sampleDataTable.AsEnumerable()
.Where(r => r.Field("序号") == ROW_ABSORPTION ||
r.Field("序号") == ROW_SOAK_TIME ||
r.Field("序号") == ROW_HANG_TIME ||
r.Field("序号") == ROW_RUN_SPEED ||
r.Field("序号") == ROW_AVG_ABSORPTION ||
r.Field("序号") == ROW_MAX_ABSORPTION ||
r.Field("序号") == ROW_STD_DEVIATION ||
r.Field("序号") == "液体吸收量平均值(%)试样1-5" ||
r.Field("序号") == "液体吸收量平均值(%)试样6-10" ||
r.Field("序号") == "液体吸收量最大值(%)试样1-5" ||
r.Field("序号") == "液体吸收量最大值(%)试样6-10" ||
r.Field("序号") == "标准偏差试样1-5" ||
r.Field("序号") == "标准偏差试样6-10")
.ToList();
foreach (var row in rowsToRemove)
{
sampleDataTable.Rows.Remove(row);
}
}
///
/// 模拟从寄存器读取数据
///
private double ReadRegisterData(int registerAddress)
{
return MIN_WEIGHT + random.NextDouble() * (MAX_WEIGHT - MIN_WEIGHT);
}
///
/// 生成模拟测试数据(精确模拟真实测试场景)
///
public void GenerateMockData()
{
sampleDataTable.Clear();
sampleCount = 0;
// 生成模拟数据
double[] initialWeights = new double[currentSampleCount];
double[] afterWeights = new double[currentSampleCount];
// 设置基准值,使数据更真实
double baseInitialWeight = 15.0; // 基准初始重量
double baseAbsorptionRate = 0.35; // 基准吸收率 35%
for (int i = 0; i < currentSampleCount; i++)
{
// 初始重量:在基准值附近波动 ±3g
initialWeights[i] = Math.Round(baseInitialWeight + (random.NextDouble() - 0.5) * 6.0, 2);
// 吸收率:在基准吸收率附近波动 ±10%
double absorptionRate = baseAbsorptionRate + (random.NextDouble() - 0.5) * 0.2;
// 浸润后重量 = 初始重量 × (1 + 吸收率)
afterWeights[i] = Math.Round(initialWeights[i] * (1 + absorptionRate), 2);
}
sampleCount = 1;
UpdateDisplay(initialWeights, afterWeights);
// 计算并显示统计信息
double[] absorptions = new double[currentSampleCount];
for (int i = 0; i < currentSampleCount; i++)
{
absorptions[i] = ((afterWeights[i] - initialWeights[i]) / initialWeights[i]) * 100;
}
double avgAbsorption = absorptions.Average();
double stdDev = CalculateStandardDeviation(absorptions);
double maxAbsorption = absorptions.Max();
double minAbsorption = absorptions.Min();
string message = $"已生成 {currentSampleCount} 个试样的模拟数据\n\n" +
$"液体吸收量统计:\n" +
$"平均值:{avgAbsorption:F2}%\n" +
$"标准偏差:{stdDev:F2}%\n" +
$"最大值:{maxAbsorption:F2}%\n" +
$"最小值:{minAbsorption:F2}%";
ShowMessage(message, "模拟数据生成");
}
///
/// 更新界面显示
///
private void UpdateDisplay(double[] initialWeights, double[] afterWeights)
{
sampleDataTable.Clear();
int count = Math.Min(initialWeights.Length, currentSampleCount);
// 1. 初始重量行
DataRow initialRow = sampleDataTable.NewRow();
initialRow["序号"] = ROW_INITIAL_WEIGHT;
for (int i = 0; i < count; i++)
{
initialRow[$"试样{i + 1}"] = initialWeights[i];
}
sampleDataTable.Rows.Add(initialRow);
// 2. 浸润后重量行
DataRow afterRow = sampleDataTable.NewRow();
afterRow["序号"] = ROW_AFTER_WEIGHT;
for (int i = 0; i < count; i++)
{
afterRow[$"试样{i + 1}"] = afterWeights[i];
}
sampleDataTable.Rows.Add(afterRow);
// 3. 液体吸收量行 (%)
DataRow absorptionRow = sampleDataTable.NewRow();
absorptionRow["序号"] = ROW_ABSORPTION;
double[] absorptions = new double[count];
for (int i = 0; i < count; i++)
{
absorptions[i] = ((afterWeights[i] - initialWeights[i]) / initialWeights[i]) * 100;
absorptionRow[$"试样{i + 1}"] = absorptions[i];
}
sampleDataTable.Rows.Add(absorptionRow);
// 4. 浸润时间行
DataRow soakTimeRow = sampleDataTable.NewRow();
soakTimeRow["序号"] = ROW_SOAK_TIME;
// 为每个试样生成浸润时间(基准60s,波动±10s)
for (int i = 1; i <= count; i++)
{
int soakTime = 60 + random.Next(-10, 11); // 50-70秒
soakTimeRow[$"试样{i}"] = $"{soakTime}s";
}
sampleDataTable.Rows.Add(soakTimeRow);
// 5. 悬挂时间行
DataRow hangTimeRow = sampleDataTable.NewRow();
hangTimeRow["序号"] = ROW_HANG_TIME;
// 为每个试样生成悬挂时间(基准30s,波动±5s)
for (int i = 1; i <= count; i++)
{
int hangTime = 30 + random.Next(-5, 6); // 25-35秒
hangTimeRow[$"试样{i}"] = $"{hangTime}s";
}
sampleDataTable.Rows.Add(hangTimeRow);
// 6. 运行速度行
DataRow runSpeedRow = sampleDataTable.NewRow();
runSpeedRow["序号"] = ROW_RUN_SPEED;
// 为每个试样生成运行速度(基准100mm/min,波动±10mm/min)
for (int i = 1; i <= count; i++)
{
int runSpeed = 100 + random.Next(-10, 11); // 90-110 mm/min
runSpeedRow[$"试样{i}"] = $"{runSpeed}mm/min";
}
sampleDataTable.Rows.Add(runSpeedRow);
// 7. 液体吸收量平均值行(试样1-5)
DataRow avgRow1 = sampleDataTable.NewRow();
avgRow1["序号"] = "液体吸收量平均值(%)试样1-5";
// 计算试样1-5的平均值
int group1Count = Math.Min(5, count);
if (group1Count > 0)
{
double avgAbsorption1 = absorptions.Take(group1Count).Average();
avgRow1["试样1"] = avgAbsorption1;
}
// 试样2-5列为空(只设置到第5列或count,取较小值)
int maxCol1 = Math.Min(5, count);
for (int i = 2; i <= maxCol1; i++)
{
avgRow1[$"试样{i}"] = DBNull.Value;
}
// 如果有试样6-10,这些列也设置为空
for (int i = 6; i <= count; i++)
{
avgRow1[$"试样{i}"] = DBNull.Value;
}
sampleDataTable.Rows.Add(avgRow1);
// 8. 液体吸收量平均值行(试样6-10)- 仅当试样数量>5时添加
if (count > 5)
{
DataRow avgRow2 = sampleDataTable.NewRow();
avgRow2["序号"] = "液体吸收量平均值(%)试样6-10";
// 计算试样6-10的平均值
int group2Count = Math.Min(5, count - 5);
if (group2Count > 0)
{
double avgAbsorption2 = absorptions.Skip(5).Take(group2Count).Average();
avgRow2["试样6"] = avgAbsorption2;
}
// 其他列为空
for (int i = 1; i <= 5; i++)
{
avgRow2[$"试样{i}"] = DBNull.Value;
}
for (int i = 7; i <= count; i++)
{
avgRow2[$"试样{i}"] = DBNull.Value;
}
sampleDataTable.Rows.Add(avgRow2);
}
// 9. 液体吸收量最大值行(试样1-5)
DataRow maxRow1 = sampleDataTable.NewRow();
maxRow1["序号"] = "液体吸收量最大值(%)试样1-5";
// 计算试样1-5的最大值
if (group1Count > 0)
{
double maxAbsorption1 = absorptions.Take(group1Count).Max();
maxRow1["试样1"] = maxAbsorption1;
}
// 试样2-5列为空
for (int i = 2; i <= maxCol1; i++)
{
maxRow1[$"试样{i}"] = DBNull.Value;
}
// 如果有试样6-10,这些列也设置为空
for (int i = 6; i <= count; i++)
{
maxRow1[$"试样{i}"] = DBNull.Value;
}
sampleDataTable.Rows.Add(maxRow1);
// 10. 液体吸收量最大值行(试样6-10)- 仅当试样数量>5时添加
if (count > 5)
{
DataRow maxRow2 = sampleDataTable.NewRow();
maxRow2["序号"] = "液体吸收量最大值(%)试样6-10";
// 计算试样6-10的最大值
int group2Count = Math.Min(5, count - 5);
if (group2Count > 0)
{
double maxAbsorption2 = absorptions.Skip(5).Take(group2Count).Max();
maxRow2["试样6"] = maxAbsorption2;
}
// 其他列为空
for (int i = 1; i <= 5; i++)
{
maxRow2[$"试样{i}"] = DBNull.Value;
}
for (int i = 7; i <= count; i++)
{
maxRow2[$"试样{i}"] = DBNull.Value;
}
sampleDataTable.Rows.Add(maxRow2);
}
// 11. 标准偏差行(试样1-5)
DataRow stdDevRow1 = sampleDataTable.NewRow();
stdDevRow1["序号"] = "标准偏差试样1-5";
// 计算试样1-5的标准偏差
if (group1Count > 1)
{
double stdDev1 = CalculateStandardDeviation(absorptions.Take(group1Count).ToArray());
stdDevRow1["试样1"] = stdDev1;
}
// 试样2-5列为空
for (int i = 2; i <= maxCol1; i++)
{
stdDevRow1[$"试样{i}"] = DBNull.Value;
}
// 如果有试样6-10,这些列也设置为空
for (int i = 6; i <= count; i++)
{
stdDevRow1[$"试样{i}"] = DBNull.Value;
}
sampleDataTable.Rows.Add(stdDevRow1);
// 12. 标准偏差行(试样6-10)- 仅当试样数量>5时添加
if (count > 5)
{
DataRow stdDevRow2 = sampleDataTable.NewRow();
stdDevRow2["序号"] = "标准偏差试样6-10";
// 计算试样6-10的标准偏差
int group2Count = Math.Min(5, count - 5);
if (group2Count > 1)
{
double stdDev2 = CalculateStandardDeviation(absorptions.Skip(5).Take(group2Count).ToArray());
stdDevRow2["试样6"] = stdDev2;
}
// 其他列为空
for (int i = 1; i <= 5; i++)
{
stdDevRow2[$"试样{i}"] = DBNull.Value;
}
for (int i = 7; i <= count; i++)
{
stdDevRow2[$"试样{i}"] = DBNull.Value;
}
sampleDataTable.Rows.Add(stdDevRow2);
}
// 刷新界面
RefreshDataGridView();
}
///
/// 计算标准偏差(样本标准偏差,n-1)
///
private double CalculateStandardDeviation(double[] values)
{
if (values == null || values.Length <= 1) return 0;
double avg = values.Average();
double sumOfSquares = values.Sum(val => Math.Pow(val - avg, 2));
// 使用样本标准偏差公式:除以 (n-1)
return Math.Sqrt(sumOfSquares / (values.Length - 1));
}
///
/// 刷新DataGridView
///
private void RefreshDataGridView()
{
if (dataGridView1.DataSource is DataTable dt)
{
dt.AcceptChanges();
dataGridView1.Refresh();
}
}
///
/// 启动数据采集
///
public void StartDataCollection()
{
dataTimer.Start();
}
///
/// 停止数据采集
///
public void StopDataCollection()
{
dataTimer.Stop();
}
///
/// 生成报表(带格式的 Excel)
///
public void GenerateReport(string filePath)
{
try
{
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("液体吸收测试报表");
// 创建样式
var styles = CreateReportStyles(workbook);
// 创建标题
CreateReportTitle(sheet, styles.titleStyle);
// 创建表头
CreateReportHeader(sheet, styles.headerStyle);
// 填充数据
FillReportData(sheet, styles.dataStyle, styles.yellowStyle);
// 设置列宽
SetReportColumnWidths(sheet);
// 保存文件
SaveWorkbook(workbook, filePath);
ShowMessage($"报表已成功生成:{filePath}", "生成成功");
}
catch (Exception ex)
{
ShowMessage($"生成报表失败:{ex.Message}", "错误", MessageBoxIcon.Error);
}
}
///
/// 创建报表样式
///
private (ICellStyle titleStyle, ICellStyle headerStyle, ICellStyle dataStyle, ICellStyle yellowStyle)
CreateReportStyles(IWorkbook workbook)
{
// 标题样式
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;
SetBorders(headerStyle);
IFont headerFont = workbook.CreateFont();
headerFont.IsBold = true;
headerStyle.SetFont(headerFont);
headerStyle.Alignment = NPOIHorizontalAlignment.Center;
// 数据样式
ICellStyle dataStyle = workbook.CreateCellStyle();
SetBorders(dataStyle);
dataStyle.Alignment = NPOIHorizontalAlignment.Center;
// 黄色背景样式
ICellStyle yellowStyle = workbook.CreateCellStyle();
yellowStyle.CloneStyleFrom(dataStyle);
yellowStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Yellow.Index;
yellowStyle.FillPattern = FillPattern.SolidForeground;
return (titleStyle, headerStyle, dataStyle, yellowStyle);
}
///
/// 设置单元格边框
///
private void SetBorders(ICellStyle style)
{
style.BorderBottom = NPOIBorderStyle.Thin;
style.BorderTop = NPOIBorderStyle.Thin;
style.BorderLeft = NPOIBorderStyle.Thin;
style.BorderRight = NPOIBorderStyle.Thin;
}
///
/// 创建报表标题
///
private void CreateReportTitle(ISheet sheet, ICellStyle titleStyle)
{
IRow titleRow = sheet.CreateRow(0);
ICell titleCell = titleRow.CreateCell(0);
titleCell.SetCellValue("液体吸收测试报表");
titleCell.CellStyle = titleStyle;
sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, currentSampleCount));
}
///
/// 创建报表表头
///
private void CreateReportHeader(ISheet sheet, ICellStyle headerStyle)
{
IRow headerRow = sheet.CreateRow(2);
// 序号列
ICell cell0 = headerRow.CreateCell(0);
cell0.SetCellValue("序号");
cell0.CellStyle = headerStyle;
// 动态创建试样列
for (int i = 1; i <= currentSampleCount; i++)
{
ICell cell = headerRow.CreateCell(i);
cell.SetCellValue($"试样{i}");
cell.CellStyle = headerStyle;
}
}
///
/// 填充报表数据
///
private void FillReportData(ISheet sheet, ICellStyle dataStyle, ICellStyle yellowStyle)
{
int rowIndex = 3;
foreach (DataRow dataRow in sampleDataTable.Rows)
{
string rowName = dataRow["序号"].ToString();
// 处理试样1-5分组行的合并单元格
if (rowName == "液体吸收量平均值(%)试样1-5" ||
rowName == "液体吸收量最大值(%)试样1-5" ||
rowName == "标准偏差试样1-5")
{
IRow row = sheet.CreateRow(rowIndex++);
// 序号列
ICell nameCell = row.CreateCell(0);
nameCell.SetCellValue(rowName);
nameCell.CellStyle = dataStyle;
// 获取试样1的值
var value = dataRow["试样1"];
if (value != null && value != DBNull.Value)
{
ICell cell = row.CreateCell(1);
cell.SetCellValue(Convert.ToDouble(value));
cell.CellStyle = yellowStyle;
// 合并试样1-5列
int group1Count = Math.Min(5, currentSampleCount);
if (group1Count > 1)
{
sheet.AddMergedRegion(new CellRangeAddress(rowIndex - 1, rowIndex - 1, 1, group1Count));
}
}
}
// 处理试样6-10分组行的合并单元格
else if (rowName == "液体吸收量平均值(%)试样6-10" ||
rowName == "液体吸收量最大值(%)试样6-10" ||
rowName == "标准偏差试样6-10")
{
IRow row = sheet.CreateRow(rowIndex++);
// 序号列
ICell nameCell = row.CreateCell(0);
nameCell.SetCellValue(rowName);
nameCell.CellStyle = dataStyle;
// 获取试样6的值
var value = dataRow["试样6"];
if (value != null && value != DBNull.Value)
{
ICell cell = row.CreateCell(6);
cell.SetCellValue(Convert.ToDouble(value));
cell.CellStyle = yellowStyle;
// 合并试样6-10列
int group2Count = Math.Min(5, currentSampleCount - 5);
if (group2Count > 1)
{
sheet.AddMergedRegion(new CellRangeAddress(rowIndex - 1, rowIndex - 1, 6, 5 + group2Count));
}
}
}
else
{
// 普通行处理
IRow row = sheet.CreateRow(rowIndex++);
// 序号列
ICell nameCell = row.CreateCell(0);
nameCell.SetCellValue(rowName);
nameCell.CellStyle = dataStyle;
// 数据列
for (int i = 1; i <= currentSampleCount; i++)
{
ICell cell = row.CreateCell(i);
var value = dataRow[$"试样{i}"];
if (value != null && value != DBNull.Value)
{
if (double.TryParse(value.ToString(), out double numValue))
{
cell.SetCellValue(numValue);
}
else
{
cell.SetCellValue(value.ToString());
}
}
cell.CellStyle = yellowStyle;
}
}
}
}
///
/// 设置报表列宽
///
private void SetReportColumnWidths(ISheet sheet)
{
sheet.SetColumnWidth(0, 25 * 256);
for (int i = 1; i <= currentSampleCount; i++)
{
sheet.SetColumnWidth(i, 18 * 256);
}
}
///
/// 保存工作簿
///
private void SaveWorkbook(IWorkbook workbook, string filePath)
{
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
workbook.Write(fs);
}
}
///
/// 清空数据
///
public void ClearData()
{
sampleDataTable.Clear();
sampleCount = 0;
RefreshDataGridView();
}
}
}