Files
NonWovenFabric/WindowsFormsApp6/Form3.cs
GukSang.Jin 1c0d725886 更新
2025-12-31 14:15:34 +08:00

841 lines
30 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 Form3 : Form
{
#region
private const int TIMER_INTERVAL = 1000;
private const string DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
private const string ROW_WICKING_TIME = "吸水时间(s)";
private const string ROW_WICKING_HEIGHT = "吸芯高度(mm)";
private const string ROW_WICKING_RATE = "芯吸速率(mm/min)";
private const string ROW_AVG_WICKING_RATE = "平均芯吸速率(mm/min)";
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 currentSampleCount = 5; // 当前试样数量,可动态调整
private readonly Random random = new Random();
#endregion
public Form3()
{
InitializeComponent();
InitializeDataTable();
InitializeTimer();
InitializeDataGridView();
InitializeEventHandlers();
}
/// <summary>
/// 设置试样数量1-20
/// </summary>
public void SetSampleCount(int count)
{
if (count < 1 || count > 20)
{
ShowMessage("试样数量必须在1-20之间", "参数错误", MessageBoxIcon.Warning);
return;
}
currentSampleCount = count;
// 重新初始化数据表和界面
sampleDataTable.Clear();
InitializeDataTable();
InitializeDataGridView();
UpdateDisplay();
}
/// <summary>
/// 初始化 DataGridView 列 - 实现2级表头
/// </summary>
private void InitializeDataGridView()
{
dataGridView1.SuspendLayout();
try
{
dataGridView1.AutoGenerateColumns = false;
dataGridView1.DataSource = null;
dataGridView1.Columns.Clear();
// 移除可能存在的事件处理器
dataGridView1.CellFormatting -= DataGridView1_CellFormatting;
dataGridView1.CellValueChanged -= DataGridView1_CellValueChanged;
dataGridView1.CellBeginEdit -= DataGridView1_CellBeginEdit;
// 创建共享样式(不设置背景色,让 AlternatingRowsDefaultCellStyle 生效)
DataGridViewCellStyle centerStyle = new DataGridViewCellStyle
{
Alignment = DataGridViewContentAlignment.MiddleCenter
};
// 序号列
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
Name = "序号",
HeaderText = "序号",
DataPropertyName = "序号",
Width = 180,
ReadOnly = true,
DefaultCellStyle = centerStyle
});
// 为每个试样添加3列2级表头试样N + 子列1/2/3
for (int i = 1; i <= currentSampleCount; i++)
{
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
Name = $"试样{i}_1",
HeaderText = $"试样{i}\n1",
DataPropertyName = $"试样{i}_1",
Width = 100,
ReadOnly = false,
DefaultCellStyle = (DataGridViewCellStyle)centerStyle.Clone()
});
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
Name = $"试样{i}_2",
HeaderText = $"试样{i}\n2",
DataPropertyName = $"试样{i}_2",
Width = 100,
ReadOnly = false,
DefaultCellStyle = (DataGridViewCellStyle)centerStyle.Clone()
});
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
{
Name = $"试样{i}_3",
HeaderText = $"试样{i}\n3",
DataPropertyName = $"试样{i}_3",
Width = 100,
ReadOnly = false,
DefaultCellStyle = (DataGridViewCellStyle)centerStyle.Clone()
});
}
// 绑定数据源
dataGridView1.DataSource = sampleDataTable;
dataGridView1.CellFormatting += DataGridView1_CellFormatting;
dataGridView1.CellValueChanged += DataGridView1_CellValueChanged;
dataGridView1.CellBeginEdit += DataGridView1_CellBeginEdit;
}
finally
{
dataGridView1.ResumeLayout();
}
}
/// <summary>
/// 单元格编辑前事件 - 动态控制哪些单元格可以编辑
/// </summary>
private void DataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
if (e.RowIndex >= 0 && e.ColumnIndex > 0)
{
string rowName = dataGridView1.Rows[e.RowIndex].Cells["序号"].Value?.ToString() ?? "";
// 吸芯高度(mm)行 - 所有列都可以编辑
if (rowName == ROW_WICKING_HEIGHT)
{
return; // 允许编辑
}
// 其他行 - 取消编辑
e.Cancel = true;
}
}
/// <summary>
/// 单元格格式化事件 - 处理数值显示格式
/// </summary>
private void DataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.RowIndex < 0 || e.ColumnIndex == 0) return; // 跳过序号列
// 格式化数值显示为2位小数
if (e.Value != null && e.Value != DBNull.Value)
{
if (double.TryParse(e.Value.ToString(), out double numValue))
{
// 如果值为0或接近0显示为空白
if (Math.Abs(numValue) < 0.001)
{
e.Value = "";
e.FormattingApplied = true;
return;
}
// 显示2位小数
e.Value = numValue.ToString("F2");
e.FormattingApplied = true;
}
}
else
{
// null 或 DBNull 显示为空白
e.Value = "";
e.FormattingApplied = true;
}
}
/// <summary>
/// 单元格值改变事件 - 手动输入后重新计算
/// </summary>
private void DataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
{
string rowName = dataGridView1.Rows[e.RowIndex].Cells["序号"].Value?.ToString() ?? "";
// 如果是吸芯高度行,任何列的修改都触发重新计算
if (rowName == ROW_WICKING_HEIGHT)
{
CalculateAllRows();
RefreshDataGridView();
}
}
}
/// <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;
clockTimer = new System.Windows.Forms.Timer
{
Interval = TIMER_INTERVAL
};
clockTimer.Tick += (s, e) => label2.Text = DateTime.Now.ToString(DATE_TIME_FORMAT);
clockTimer.Start();
}
/// <summary>
/// 连接设备按钮点击事件
/// </summary>
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("开始数据采集");
}
}
/// <summary>
/// 打印按钮点击事件
/// </summary>
private void Button2_Click(object sender, EventArgs e)
{
ShowMessage("打印功能开发中...");
}
/// <summary>
/// 更新按钮状态
/// </summary>
private void UpdateButtonState(Button button, string text, Color backColor)
{
button.Text = text;
button.BackColor = backColor;
}
/// <summary>
/// 显示提示消息
/// </summary>
private void ShowMessage(string message, string title = "提示", MessageBoxIcon icon = MessageBoxIcon.Information)
{
MessageBox.Show(message, title, MessageBoxButtons.OK, icon);
}
/// <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));
// 为每个试样添加3列试样次数1、2、3
for (int i = 1; i <= currentSampleCount; i++)
{
sampleDataTable.Columns.Add($"试样{i}_1", typeof(double));
sampleDataTable.Columns.Add($"试样{i}_2", typeof(double));
sampleDataTable.Columns.Add($"试样{i}_3", typeof(double));
}
// 初始化5行数据
AddDataRow(ROW_WICKING_TIME);
AddDataRow(ROW_WICKING_HEIGHT);
AddDataRow(ROW_WICKING_RATE);
AddDataRow(ROW_AVG_WICKING_RATE);
AddDataRow(ROW_STD_DEVIATION);
}
/// <summary>
/// 添加数据行
/// </summary>
private void AddDataRow(string rowName)
{
DataRow row = sampleDataTable.NewRow();
row["序号"] = rowName;
// 初始化所有数值列为0
for (int i = 1; i <= currentSampleCount; i++)
{
row[$"试样{i}_1"] = 0.0;
row[$"试样{i}_2"] = 0.0;
row[$"试样{i}_3"] = 0.0;
}
sampleDataTable.Rows.Add(row);
}
/// <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)
{
// 第1行读取吸水时间(s) - 从寄存器读取每个试样读取3次
DataRow timeRow = sampleDataTable.Rows[0];
for (int i = 1; i <= currentSampleCount; i++)
{
double time1 = ReadRegisterData((i - 1) * 3); // 第1次测试
double time2 = ReadRegisterData((i - 1) * 3 + 1); // 第2次测试
double time3 = ReadRegisterData((i - 1) * 3 + 2); // 第3次测试
timeRow[$"试样{i}_1"] = time1;
timeRow[$"试样{i}_2"] = time2;
timeRow[$"试样{i}_3"] = time3;
}
UpdateDisplay();
}
/// <summary>
/// 模拟从寄存器读取数据
/// </summary>
private double ReadRegisterData(int registerAddress)
{
// 吸水时间寄存器30-34秒
return 30 + random.NextDouble() * 4;
}
/// <summary>
/// 生成模拟测试数据
/// </summary>
public void GenerateMockData()
{
// 清空所有行的数据(保持表结构)
foreach (DataRow row in sampleDataTable.Rows)
{
for (int i = 1; i <= currentSampleCount; i++)
{
row[$"试样{i}_1"] = 0.0;
row[$"试样{i}_2"] = 0.0;
row[$"试样{i}_3"] = 0.0;
}
}
// 第1行吸水时间s- 系统读数每个试样3次
DataRow timeRow = sampleDataTable.Rows[0];
for (int i = 1; i <= currentSampleCount; i++)
{
// 生成3次测试的吸水时间数据30-34秒略有差异
double baseTime = 31 + random.NextDouble() * 2; // 基准时间 31-33秒
double time1 = Math.Round(baseTime + (random.NextDouble() - 0.5) * 2, 2); // ±1秒
double time2 = Math.Round(baseTime + (random.NextDouble() - 0.5) * 2, 2);
double time3 = Math.Round(baseTime + (random.NextDouble() - 0.5) * 2, 2);
timeRow[$"试样{i}_1"] = time1;
timeRow[$"试样{i}_2"] = time2;
timeRow[$"试样{i}_3"] = time3;
}
// 第2行吸芯高度mm- 手动输入,不自动生成
// 保持为0等待用户手动输入
// 第3-5行芯吸速率、平均值、标准偏差 - 保持为0
// 等待用户输入吸芯高度后,会自动计算
// 更新显示
RefreshDataGridView();
ShowMessage($"已生成 {currentSampleCount} 个试样的吸水时间数据\n" +
$"- 吸水时间30-34秒系统读数每个试样3次\n" +
$"- 吸芯高度请手动输入每个试样3次测试\n" +
$"- 芯吸速率:输入吸芯高度后自动计算",
"模拟数据生成");
}
/// <summary>
/// 更新界面显示
/// </summary>
private void UpdateDisplay()
{
RefreshDataGridView();
}
/// <summary>
/// 刷新DataGridView
/// </summary>
private void RefreshDataGridView()
{
if (dataGridView1.DataSource is DataTable dt)
{
dt.AcceptChanges();
dataGridView1.Refresh();
}
}
/// <summary>
/// 计算所有行的数据
/// </summary>
private void CalculateAllRows()
{
// 第3行芯吸速率mm/min= 吸芯高度 / (吸水时间 / 60)
CalculateWickingRate();
// 第4行平均芯吸速率mm/min
CalculateAverageWickingRate();
// 第5行标准偏差
CalculateStandardDeviation();
}
/// <summary>
/// 计算芯吸速率mm/min
/// 公式:芯吸速率 = 吸芯高度mm / (吸水时间s / 60)
/// </summary>
private void CalculateWickingRate()
{
DataRow timeRow = sampleDataTable.Rows[0]; // 吸水时间
DataRow heightRow = sampleDataTable.Rows[1]; // 吸芯高度
DataRow rateRow = sampleDataTable.Rows[2]; // 芯吸速率
for (int i = 1; i <= currentSampleCount; i++)
{
// 获取3次吸水时间测试数据
double time1 = ConvertToDouble(timeRow[$"试样{i}_1"]);
double time2 = ConvertToDouble(timeRow[$"试样{i}_2"]);
double time3 = ConvertToDouble(timeRow[$"试样{i}_3"]);
// 获取3次吸芯高度测试数据
double height1 = ConvertToDouble(heightRow[$"试样{i}_1"]);
double height2 = ConvertToDouble(heightRow[$"试样{i}_2"]);
double height3 = ConvertToDouble(heightRow[$"试样{i}_3"]);
// 计算3次芯吸速率每次测试独立计算使用对应的时间和高度
double rate1 = (time1 > 0 && height1 > 0) ? height1 / (time1 / 60.0) : 0;
double rate2 = (time2 > 0 && height2 > 0) ? height2 / (time2 / 60.0) : 0;
double rate3 = (time3 > 0 && height3 > 0) ? height3 / (time3 / 60.0) : 0;
// 存储到对应的列
rateRow[$"试样{i}_1"] = Math.Round(rate1, 2);
rateRow[$"试样{i}_2"] = Math.Round(rate2, 2);
rateRow[$"试样{i}_3"] = Math.Round(rate3, 2);
}
}
/// <summary>
/// 安全地将对象转换为double处理DBNull和null情况
/// </summary>
private double ConvertToDouble(object value)
{
if (value == null || value == DBNull.Value)
{
return 0.0;
}
if (double.TryParse(value.ToString(), out double result))
{
return result;
}
return 0.0;
}
/// <summary>
/// 计算平均芯吸速率mm/min
/// </summary>
private void CalculateAverageWickingRate()
{
DataRow rateRow = sampleDataTable.Rows[2]; // 芯吸速率
DataRow avgRow = sampleDataTable.Rows[3]; // 平均芯吸速率
List<double> rates = new List<double>();
for (int i = 1; i <= currentSampleCount; i++)
{
double rate = ConvertToDouble(rateRow[$"试样{i}_3"]);
if (rate > 0)
{
rates.Add(rate);
}
}
double average = rates.Count > 0 ? rates.Average() : 0;
// 所有试样显示相同的平均值存储在试样次数3
for (int i = 1; i <= currentSampleCount; i++)
{
avgRow[$"试样{i}_3"] = Math.Round(average, 2);
}
}
/// <summary>
/// 计算标准偏差
/// </summary>
private void CalculateStandardDeviation()
{
DataRow rateRow = sampleDataTable.Rows[2]; // 芯吸速率
DataRow stdRow = sampleDataTable.Rows[4]; // 标准偏差
List<double> rates = new List<double>();
for (int i = 1; i <= currentSampleCount; i++)
{
double rate = ConvertToDouble(rateRow[$"试样{i}_3"]);
if (rate > 0)
{
rates.Add(rate);
}
}
double stdDev = 0;
if (rates.Count > 1)
{
double average = rates.Average();
double sumOfSquares = rates.Sum(r => Math.Pow(r - average, 2));
stdDev = Math.Sqrt(sumOfSquares / (rates.Count - 1));
}
// 所有试样显示相同的标准偏差存储在试样次数3
for (int i = 1; i <= currentSampleCount; i++)
{
stdRow[$"试样{i}_3"] = Math.Round(stdDev, 2);
}
}
/// <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 = filePath.EndsWith(".xlsx")
? (IWorkbook)new XSSFWorkbook()
: new HSSFWorkbook();
ISheet sheet = workbook.CreateSheet("液体芯吸速率测试报表");
// 创建样式
var styles = CreateReportStyles(workbook);
// 创建表头2级
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);
}
}
/// <summary>
/// 创建报表样式
/// </summary>
private (ICellStyle headerStyle, ICellStyle dataStyle, ICellStyle yellowStyle)
CreateReportStyles(IWorkbook workbook)
{
// 表头样式
ICellStyle headerStyle = workbook.CreateCellStyle();
headerStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;
headerStyle.FillPattern = FillPattern.SolidForeground;
SetBorders(headerStyle);
headerStyle.Alignment = NPOIHorizontalAlignment.Center;
headerStyle.VerticalAlignment = VerticalAlignment.Center;
IFont headerFont = workbook.CreateFont();
headerFont.IsBold = true;
headerStyle.SetFont(headerFont);
// 白色背景样式
ICellStyle dataStyle = workbook.CreateCellStyle();
SetBorders(dataStyle);
dataStyle.Alignment = NPOIHorizontalAlignment.Center;
dataStyle.VerticalAlignment = VerticalAlignment.Center;
// 黄色背景样式
ICellStyle yellowStyle = workbook.CreateCellStyle();
yellowStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.LightYellow.Index;
yellowStyle.FillPattern = FillPattern.SolidForeground;
SetBorders(yellowStyle);
yellowStyle.Alignment = NPOIHorizontalAlignment.Center;
yellowStyle.VerticalAlignment = VerticalAlignment.Center;
return (headerStyle, dataStyle, yellowStyle);
}
/// <summary>
/// 设置单元格边框
/// </summary>
private void SetBorders(ICellStyle style)
{
style.BorderBottom = NPOIBorderStyle.Thin;
style.BorderTop = NPOIBorderStyle.Thin;
style.BorderLeft = NPOIBorderStyle.Thin;
style.BorderRight = NPOIBorderStyle.Thin;
}
/// <summary>
/// 创建报表表头2级
/// </summary>
private void CreateReportHeader(ISheet sheet, ICellStyle headerStyle)
{
// 创建第一行表头试样1-N
IRow headerRow1 = sheet.CreateRow(0);
headerRow1.Height = 400;
ICell cell0 = headerRow1.CreateCell(0);
cell0.SetCellValue("序号");
cell0.CellStyle = headerStyle;
sheet.AddMergedRegion(new CellRangeAddress(0, 1, 0, 0)); // 合并序号列
int colIndex = 1;
for (int i = 1; i <= currentSampleCount; i++)
{
ICell cell = headerRow1.CreateCell(colIndex);
cell.SetCellValue($"试样{i}");
cell.CellStyle = headerStyle;
sheet.AddMergedRegion(new CellRangeAddress(0, 0, colIndex, colIndex + 2));
colIndex += 3;
}
// 创建第二行表头试样次数1、2、3
IRow headerRow2 = sheet.CreateRow(1);
headerRow2.Height = 400;
colIndex = 1;
for (int i = 1; i <= currentSampleCount; i++)
{
ICell cell1 = headerRow2.CreateCell(colIndex++);
cell1.SetCellValue("1");
cell1.CellStyle = headerStyle;
ICell cell2 = headerRow2.CreateCell(colIndex++);
cell2.SetCellValue("2");
cell2.CellStyle = headerStyle;
ICell cell3 = headerRow2.CreateCell(colIndex++);
cell3.SetCellValue("3");
cell3.CellStyle = headerStyle;
}
}
/// <summary>
/// 填充报表数据
/// </summary>
private void FillReportData(ISheet sheet, ICellStyle dataStyle, ICellStyle yellowStyle)
{
int rowIndex = 2;
int dataRowIndex = 0;
foreach (DataRow dataRow in sampleDataTable.Rows)
{
IRow row = sheet.CreateRow(rowIndex);
row.Height = 380;
// 根据行索引选择样式(隔行变色)
ICellStyle rowStyle = (dataRowIndex % 2 == 0) ? dataStyle : yellowStyle;
// 序号列
ICell cellSeq = row.CreateCell(0);
cellSeq.SetCellValue(dataRow["序号"].ToString());
cellSeq.CellStyle = rowStyle;
int colIndex = 1;
for (int i = 1; i <= currentSampleCount; i++)
{
// 试样次数1
ICell cell1 = row.CreateCell(colIndex++);
double val1 = ConvertToDouble(dataRow[$"试样{i}_1"]);
if (Math.Abs(val1) >= 0.001) // 只有非0值才显示
{
cell1.SetCellValue(val1);
}
cell1.CellStyle = rowStyle;
// 试样次数2
ICell cell2 = row.CreateCell(colIndex++);
double val2 = ConvertToDouble(dataRow[$"试样{i}_2"]);
if (Math.Abs(val2) >= 0.001) // 只有非0值才显示
{
cell2.SetCellValue(val2);
}
cell2.CellStyle = rowStyle;
// 试样次数3
ICell cell3 = row.CreateCell(colIndex++);
double val3 = ConvertToDouble(dataRow[$"试样{i}_3"]);
if (Math.Abs(val3) >= 0.001) // 只有非0值才显示
{
cell3.SetCellValue(val3);
}
cell3.CellStyle = rowStyle;
}
rowIndex++;
dataRowIndex++;
}
}
/// <summary>
/// 设置报表列宽
/// </summary>
private void SetReportColumnWidths(ISheet sheet)
{
sheet.SetColumnWidth(0, 20 * 256); // 序号列
int totalColumns = currentSampleCount * 3;
for (int i = 1; i <= totalColumns; i++)
{
sheet.SetColumnWidth(i, 12 * 256); // 数据列
}
}
/// <summary>
/// 保存工作簿
/// </summary>
private void SaveWorkbook(IWorkbook workbook, string filePath)
{
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
workbook.Write(fs);
}
}
/// <summary>
/// 生成报表(带格式的 Excel
/// </summary>
public void GenerateReport(string filePath)
{
// 使用 ExportToExcel 方法
ExportToExcel(filePath);
}
/// <summary>
/// 清空数据
/// </summary>
public void ClearData()
{
sampleDataTable.Clear();
InitializeDataTable();
RefreshDataGridView();
}
}
}