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(); } } }