810 lines
34 KiB
C#
810 lines
34 KiB
C#
using System;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.Windows.Forms;
|
||
using System.IO;
|
||
using NPOI.SS.UserModel;
|
||
using NPOI.XSSF.UserModel;
|
||
using NPOI.SS.Util;
|
||
using NPOIBorderStyle = NPOI.SS.UserModel.BorderStyle;
|
||
using NPOIHorizontalAlignment = NPOI.SS.UserModel.HorizontalAlignment;
|
||
|
||
namespace WindowsFormsApp6
|
||
{
|
||
public partial class MainForm : Form
|
||
{
|
||
private Form1 form1Instance;
|
||
private Form2 form2Instance;
|
||
private Form3 form3Instance;
|
||
private System.Windows.Forms.Timer clockTimer;
|
||
|
||
public MainForm()
|
||
{
|
||
InitializeComponent();
|
||
InitializeClockTimer();
|
||
InitializeTabControl();
|
||
InitializeEmbeddedForms();
|
||
}
|
||
|
||
private void InitializeClockTimer()
|
||
{
|
||
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();
|
||
}
|
||
|
||
private void InitializeTabControl()
|
||
{
|
||
tabControl1.SelectedIndexChanged += TabControl1_SelectedIndexChanged;
|
||
}
|
||
|
||
private void TabControl1_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
UpdateTitleForCurrentTab();
|
||
|
||
// 根据选中的 Tab 显示/隐藏切换布局按钮
|
||
// 只有在 Form3 (Tab 2, index=2) 时显示切换按钮
|
||
buttonToggleLayout.Visible = (tabControl1.SelectedIndex == 2);
|
||
|
||
// 更新切换按钮的文本
|
||
if (tabControl1.SelectedIndex == 2 && form3Instance != null)
|
||
{
|
||
UpdateToggleButtonText();
|
||
}
|
||
}
|
||
|
||
private void UpdateTitleForCurrentTab()
|
||
{
|
||
switch (tabControl1.SelectedIndex)
|
||
{
|
||
case 0:
|
||
label1.Text = " 液体吸收时间测试报告";
|
||
break;
|
||
case 1:
|
||
label1.Text = " 液体吸收量测试报告";
|
||
break;
|
||
case 2:
|
||
label1.Text = " 液体芯吸速率测试报告";
|
||
break;
|
||
}
|
||
}
|
||
|
||
private void InitializeEmbeddedForms()
|
||
{
|
||
form1Instance = new Form1();
|
||
form1Instance.TopLevel = false;
|
||
form1Instance.FormBorderStyle = FormBorderStyle.None;
|
||
form1Instance.Dock = DockStyle.Fill;
|
||
|
||
Panel panel1 = new Panel();
|
||
panel1.Dock = DockStyle.Fill;
|
||
panel1.Controls.Add(form1Instance.Controls["tableLayoutPanel1"].Controls["panel3"]);
|
||
tabPage1.Controls.Add(panel1);
|
||
form1Instance.Show();
|
||
|
||
form2Instance = new Form2();
|
||
form2Instance.TopLevel = false;
|
||
form2Instance.FormBorderStyle = FormBorderStyle.None;
|
||
form2Instance.Dock = DockStyle.Fill;
|
||
|
||
Panel panel2 = new Panel();
|
||
panel2.Dock = DockStyle.Fill;
|
||
panel2.Controls.Add(form2Instance.Controls["tableLayoutPanel1"].Controls["panel3"]);
|
||
tabPage2.Controls.Add(panel2);
|
||
form2Instance.Show();
|
||
|
||
form3Instance = new Form3();
|
||
form3Instance.TopLevel = false;
|
||
form3Instance.FormBorderStyle = FormBorderStyle.None;
|
||
form3Instance.Dock = DockStyle.Fill;
|
||
|
||
Panel panel3 = new Panel();
|
||
panel3.Dock = DockStyle.Fill;
|
||
panel3.Controls.Add(form3Instance.Controls["tableLayoutPanel1"].Controls["panel3"]);
|
||
tabPage3.Controls.Add(panel3);
|
||
form3Instance.Show();
|
||
}
|
||
|
||
private void buttonPrint_Click(object sender, EventArgs e)
|
||
{
|
||
MessageBox.Show("打印功能开发中", "提示");
|
||
}
|
||
|
||
private void buttonExport_Click(object sender, EventArgs e)
|
||
{
|
||
SaveFileDialog saveFileDialog = new SaveFileDialog
|
||
{
|
||
Filter = "Excel 文件 (*.xlsx)|*.xlsx",
|
||
FileName = $"测试报告_{DateTime.Now:yyyyMMdd_HHmmss}",
|
||
Title = "导出整合报告"
|
||
};
|
||
|
||
if (saveFileDialog.ShowDialog() == DialogResult.OK)
|
||
{
|
||
ExportIntegratedReport(saveFileDialog.FileName);
|
||
}
|
||
}
|
||
|
||
private void button5_Click(object sender, EventArgs e)
|
||
{
|
||
switch (tabControl1.SelectedIndex)
|
||
{
|
||
case 0:
|
||
form1Instance.GenerateMockData();
|
||
break;
|
||
case 1:
|
||
form2Instance.GenerateMockData();
|
||
break;
|
||
case 2:
|
||
form3Instance.GenerateMockData();
|
||
break;
|
||
}
|
||
}
|
||
|
||
private void buttonToggleLayout_Click(object sender, EventArgs e)
|
||
{
|
||
if (form3Instance != null)
|
||
{
|
||
// 调用 Form3 的公共切换方法
|
||
form3Instance.ToggleTableLayout();
|
||
|
||
// 更新按钮文本
|
||
UpdateToggleButtonText();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新切换按钮的文本
|
||
/// </summary>
|
||
private void UpdateToggleButtonText()
|
||
{
|
||
if (form3Instance != null)
|
||
{
|
||
// 使用公共方法获取布局状态
|
||
bool isVertical = form3Instance.IsVerticalLayout();
|
||
buttonToggleLayout.Text = isVertical ? "🔄 横向布局" : "🔄 纵向布局";
|
||
}
|
||
}
|
||
|
||
private void ExportIntegratedReport(string filePath)
|
||
{
|
||
try
|
||
{
|
||
IWorkbook workbook = new XSSFWorkbook();
|
||
|
||
// 创建单个整合的工作表
|
||
CreateIntegratedSheet(workbook);
|
||
|
||
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
|
||
{
|
||
workbook.Write(fs);
|
||
}
|
||
|
||
MessageBox.Show($"导出成功:{filePath}", "成功");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"导出失败:{ex.Message}", "错误");
|
||
}
|
||
}
|
||
|
||
private void CreateIntegratedSheet(IWorkbook workbook)
|
||
{
|
||
ISheet sheet = workbook.CreateSheet("吸收性测试报告");
|
||
var styles = CreateReportStyles(workbook);
|
||
|
||
// 获取三个表单的数据
|
||
var sampleCountField1 = form1Instance.GetType()
|
||
.GetField("currentSampleCount", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||
int sampleCount = sampleCountField1 != null ? (int)sampleCountField1.GetValue(form1Instance) : 5;
|
||
|
||
var dataTableField1 = form1Instance.GetType()
|
||
.GetField("sampleDataTable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||
DataTable dataTable1 = dataTableField1?.GetValue(form1Instance) as DataTable;
|
||
|
||
var dataTableField2 = form2Instance.GetType()
|
||
.GetField("sampleDataTable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||
DataTable dataTable2 = dataTableField2?.GetValue(form2Instance) as DataTable;
|
||
|
||
var dataTableField3 = form3Instance.GetType()
|
||
.GetField("sampleDataTable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||
DataTable dataTable3 = dataTableField3?.GetValue(form3Instance) as DataTable;
|
||
|
||
int currentRow = 0;
|
||
|
||
// 1. 创建总标题
|
||
IRow titleRow = sheet.CreateRow(currentRow++);
|
||
titleRow.Height = 800;
|
||
ICell titleCell = titleRow.CreateCell(0);
|
||
titleCell.SetCellValue("吸收性测试报告");
|
||
titleCell.CellStyle = styles.titleStyle;
|
||
// 为合并区域的所有单元格设置样式(总标题不需要边框,但为了一致性也设置)
|
||
for (int i = 1; i <= sampleCount + 5; i++)
|
||
{
|
||
titleRow.CreateCell(i).CellStyle = styles.titleStyle;
|
||
}
|
||
sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, sampleCount + 5));
|
||
|
||
currentRow++; // 空行
|
||
|
||
// 2. 创建信息输入区域
|
||
CreateInfoSection(sheet, ref currentRow, sampleCount, styles);
|
||
|
||
currentRow++; // 空行
|
||
|
||
// 3. 创建液体吸收时间部分
|
||
CreateForm1Section(sheet, ref currentRow, sampleCount, dataTable1, styles);
|
||
|
||
currentRow++; // 空行
|
||
|
||
// 4. 创建液体吸收量部分
|
||
CreateForm2Section(sheet, ref currentRow, sampleCount, dataTable2, styles);
|
||
|
||
currentRow++; // 空行
|
||
|
||
// 5. 创建液体芯吸速率部分
|
||
CreateForm3Section(sheet, ref currentRow, sampleCount, dataTable3, styles);
|
||
|
||
// 设置列宽
|
||
sheet.SetColumnWidth(0, 20 * 256);
|
||
for (int i = 1; i <= sampleCount * 3; i++)
|
||
{
|
||
sheet.SetColumnWidth(i, 12 * 256);
|
||
}
|
||
}
|
||
|
||
private void CreateInfoSection(ISheet sheet, ref int currentRow, int sampleCount,
|
||
(ICellStyle titleStyle, ICellStyle headerStyle, ICellStyle dataStyle, ICellStyle yellowStyle) styles)
|
||
{
|
||
// 从界面获取实际数据
|
||
string sampleName = textBox1.Text.Trim();
|
||
string materialCode = textBox2.Text.Trim();
|
||
string batchNumber = textBox3.Text.Trim();
|
||
string operatorName = textBox4.Text.Trim();
|
||
string instrument = textBox5.Text.Trim();
|
||
string deviceNumber = textBox6.Text.Trim();
|
||
string testTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||
|
||
// 第一行信息
|
||
IRow infoRow1 = sheet.CreateRow(currentRow++);
|
||
infoRow1.Height = 400;
|
||
|
||
// 样品名称
|
||
ICell cell1 = infoRow1.CreateCell(0);
|
||
cell1.SetCellValue("样品名称:");
|
||
cell1.CellStyle = styles.dataStyle;
|
||
|
||
ICell cell2 = infoRow1.CreateCell(1);
|
||
cell2.SetCellValue(string.IsNullOrEmpty(sampleName) ? "" : sampleName);
|
||
cell2.CellStyle = styles.yellowStyle;
|
||
// 为合并区域的所有单元格设置样式
|
||
infoRow1.CreateCell(2).CellStyle = styles.yellowStyle;
|
||
sheet.AddMergedRegion(new CellRangeAddress(currentRow - 1, currentRow - 1, 1, 2));
|
||
|
||
// 物料编码
|
||
ICell cell3 = infoRow1.CreateCell(3);
|
||
cell3.SetCellValue("物料编码:");
|
||
cell3.CellStyle = styles.dataStyle;
|
||
|
||
ICell cell4 = infoRow1.CreateCell(4);
|
||
cell4.SetCellValue(string.IsNullOrEmpty(materialCode) ? "" : materialCode);
|
||
cell4.CellStyle = styles.yellowStyle;
|
||
// 为合并区域的所有单元格设置样式
|
||
infoRow1.CreateCell(5).CellStyle = styles.yellowStyle;
|
||
sheet.AddMergedRegion(new CellRangeAddress(currentRow - 1, currentRow - 1, 4, 5));
|
||
|
||
// 批号
|
||
ICell cell5 = infoRow1.CreateCell(6);
|
||
cell5.SetCellValue("批号:");
|
||
cell5.CellStyle = styles.dataStyle;
|
||
|
||
ICell cell6 = infoRow1.CreateCell(7);
|
||
cell6.SetCellValue(string.IsNullOrEmpty(batchNumber) ? "" : batchNumber);
|
||
cell6.CellStyle = styles.yellowStyle;
|
||
|
||
// 操作人员
|
||
ICell cell7 = infoRow1.CreateCell(8);
|
||
cell7.SetCellValue("操作人员:");
|
||
cell7.CellStyle = styles.dataStyle;
|
||
|
||
ICell cell8 = infoRow1.CreateCell(9);
|
||
cell8.SetCellValue(string.IsNullOrEmpty(operatorName) ? "" : operatorName);
|
||
cell8.CellStyle = styles.yellowStyle;
|
||
|
||
// 第二行信息
|
||
IRow infoRow2 = sheet.CreateRow(currentRow++);
|
||
infoRow2.Height = 400;
|
||
|
||
// 测试时间
|
||
ICell cell21 = infoRow2.CreateCell(0);
|
||
cell21.SetCellValue("测试时间:");
|
||
cell21.CellStyle = styles.dataStyle;
|
||
|
||
ICell cell22 = infoRow2.CreateCell(1);
|
||
cell22.SetCellValue(testTime);
|
||
cell22.CellStyle = styles.yellowStyle;
|
||
// 为合并区域的所有单元格设置样式
|
||
infoRow2.CreateCell(2).CellStyle = styles.yellowStyle;
|
||
sheet.AddMergedRegion(new CellRangeAddress(currentRow - 1, currentRow - 1, 1, 2));
|
||
|
||
// 仪器
|
||
ICell cell23 = infoRow2.CreateCell(3);
|
||
cell23.SetCellValue("仪器:");
|
||
cell23.CellStyle = styles.dataStyle;
|
||
|
||
ICell cell24 = infoRow2.CreateCell(4);
|
||
cell24.SetCellValue(string.IsNullOrEmpty(instrument) ? "" : instrument);
|
||
cell24.CellStyle = styles.yellowStyle;
|
||
// 为合并区域的所有单元格设置样式
|
||
infoRow2.CreateCell(5).CellStyle = styles.yellowStyle;
|
||
sheet.AddMergedRegion(new CellRangeAddress(currentRow - 1, currentRow - 1, 4, 5));
|
||
|
||
// 设备编号
|
||
ICell cell25 = infoRow2.CreateCell(6);
|
||
cell25.SetCellValue("设备编号:");
|
||
cell25.CellStyle = styles.dataStyle;
|
||
|
||
ICell cell26 = infoRow2.CreateCell(7);
|
||
cell26.SetCellValue(string.IsNullOrEmpty(deviceNumber) ? "" : deviceNumber);
|
||
cell26.CellStyle = styles.yellowStyle;
|
||
|
||
// 数据文件
|
||
ICell cell27 = infoRow2.CreateCell(8);
|
||
cell27.SetCellValue("数据文件:");
|
||
cell27.CellStyle = styles.dataStyle;
|
||
|
||
ICell cell28 = infoRow2.CreateCell(9);
|
||
cell28.SetCellValue("(报告保存路径)");
|
||
cell28.CellStyle = styles.yellowStyle;
|
||
}
|
||
|
||
private void CreateForm1Section(ISheet sheet, ref int currentRow, int sampleCount, DataTable dataTable,
|
||
(ICellStyle titleStyle, ICellStyle headerStyle, ICellStyle dataStyle, ICellStyle yellowStyle) styles)
|
||
{
|
||
// 子标题
|
||
IRow subtitleRow = sheet.CreateRow(currentRow++);
|
||
subtitleRow.Height = 500;
|
||
ICell subtitleCell = subtitleRow.CreateCell(0);
|
||
subtitleCell.SetCellValue("液体吸收时间");
|
||
subtitleCell.CellStyle = styles.headerStyle;
|
||
// 为合并区域的所有单元格设置样式
|
||
for (int i = 1; i <= sampleCount; i++)
|
||
{
|
||
subtitleRow.CreateCell(i).CellStyle = styles.headerStyle;
|
||
}
|
||
sheet.AddMergedRegion(new CellRangeAddress(currentRow - 1, currentRow - 1, 0, sampleCount));
|
||
|
||
// 表头
|
||
IRow headerRow = sheet.CreateRow(currentRow++);
|
||
headerRow.Height = 400;
|
||
ICell seqCell = headerRow.CreateCell(0);
|
||
seqCell.SetCellValue("序号");
|
||
seqCell.CellStyle = styles.headerStyle;
|
||
|
||
for (int i = 1; i <= sampleCount; i++)
|
||
{
|
||
ICell cell = headerRow.CreateCell(i);
|
||
cell.SetCellValue($"试样{i}");
|
||
cell.CellStyle = styles.headerStyle;
|
||
}
|
||
|
||
// 数据行
|
||
if (dataTable != null && dataTable.Rows.Count > 0)
|
||
{
|
||
foreach (DataRow dataRow in dataTable.Rows)
|
||
{
|
||
string rowName = dataRow["序号"]?.ToString() ?? "";
|
||
if (string.IsNullOrEmpty(rowName)) continue;
|
||
|
||
IRow row = sheet.CreateRow(currentRow++);
|
||
row.Height = 380;
|
||
|
||
ICell nameCell = row.CreateCell(0);
|
||
nameCell.SetCellValue(rowName);
|
||
nameCell.CellStyle = styles.dataStyle;
|
||
|
||
// 如果是平均时间行,只显示一个合并的单元格
|
||
if (rowName.Contains("平均"))
|
||
{
|
||
ICell avgCell = row.CreateCell(1);
|
||
if (dataTable.Columns.Contains("试样1") && dataRow["试样1"] != DBNull.Value)
|
||
{
|
||
if (double.TryParse(dataRow["试样1"].ToString(), out double value))
|
||
{
|
||
avgCell.SetCellValue(value);
|
||
}
|
||
else
|
||
{
|
||
avgCell.SetCellValue("");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
avgCell.SetCellValue("");
|
||
}
|
||
avgCell.CellStyle = styles.yellowStyle;
|
||
|
||
// 为合并区域的其他单元格设置样式
|
||
for (int i = 2; i <= sampleCount; i++)
|
||
{
|
||
row.CreateCell(i).CellStyle = styles.yellowStyle;
|
||
}
|
||
// 合并平均时间单元格
|
||
sheet.AddMergedRegion(new CellRangeAddress(currentRow - 1, currentRow - 1, 1, sampleCount));
|
||
}
|
||
else
|
||
{
|
||
// 普通数据行,显示每个试样的数据
|
||
for (int i = 1; i <= sampleCount; i++)
|
||
{
|
||
ICell cell = row.CreateCell(i);
|
||
if (dataTable.Columns.Contains($"试样{i}") && dataRow[$"试样{i}"] != DBNull.Value)
|
||
{
|
||
if (double.TryParse(dataRow[$"试样{i}"].ToString(), out double value))
|
||
{
|
||
cell.SetCellValue(value);
|
||
}
|
||
else
|
||
{
|
||
cell.SetCellValue("");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
cell.SetCellValue("");
|
||
}
|
||
cell.CellStyle = styles.yellowStyle;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private void CreateForm2Section(ISheet sheet, ref int currentRow, int sampleCount, DataTable dataTable,
|
||
(ICellStyle titleStyle, ICellStyle headerStyle, ICellStyle dataStyle, ICellStyle yellowStyle) styles)
|
||
{
|
||
// 子标题
|
||
IRow subtitleRow = sheet.CreateRow(currentRow++);
|
||
subtitleRow.Height = 500;
|
||
ICell subtitleCell = subtitleRow.CreateCell(0);
|
||
subtitleCell.SetCellValue("液体吸收量");
|
||
subtitleCell.CellStyle = styles.headerStyle;
|
||
// 为合并区域的所有单元格设置样式
|
||
for (int i = 1; i <= sampleCount; i++)
|
||
{
|
||
subtitleRow.CreateCell(i).CellStyle = styles.headerStyle;
|
||
}
|
||
sheet.AddMergedRegion(new CellRangeAddress(currentRow - 1, currentRow - 1, 0, sampleCount));
|
||
|
||
// 表头
|
||
IRow headerRow = sheet.CreateRow(currentRow++);
|
||
headerRow.Height = 400;
|
||
ICell seqCell = headerRow.CreateCell(0);
|
||
seqCell.SetCellValue("序号");
|
||
seqCell.CellStyle = styles.headerStyle;
|
||
|
||
for (int i = 1; i <= sampleCount; i++)
|
||
{
|
||
ICell cell = headerRow.CreateCell(i);
|
||
cell.SetCellValue($"试样{i}");
|
||
cell.CellStyle = styles.headerStyle;
|
||
}
|
||
|
||
// 数据行
|
||
if (dataTable != null && dataTable.Rows.Count > 0)
|
||
{
|
||
foreach (DataRow dataRow in dataTable.Rows)
|
||
{
|
||
string rowName = dataRow["序号"]?.ToString() ?? "";
|
||
if (string.IsNullOrEmpty(rowName)) continue;
|
||
|
||
IRow row = sheet.CreateRow(currentRow++);
|
||
row.Height = 380;
|
||
|
||
ICell nameCell = row.CreateCell(0);
|
||
nameCell.SetCellValue(rowName);
|
||
nameCell.CellStyle = styles.dataStyle;
|
||
|
||
// 判断是否是需要合并的行(平均值、最大值、标准偏差)
|
||
bool isMergedRow = rowName.Contains("平均值") || rowName.Contains("最大值") || rowName.Contains("标准偏差");
|
||
|
||
if (isMergedRow)
|
||
{
|
||
// 合并为一列,只显示第一个试样的值
|
||
ICell valueCell = row.CreateCell(1);
|
||
if (dataTable.Columns.Contains("试样1") && dataRow["试样1"] != DBNull.Value)
|
||
{
|
||
object value = dataRow["试样1"];
|
||
if (value != null && double.TryParse(value.ToString(), out double numValue))
|
||
{
|
||
valueCell.SetCellValue(numValue);
|
||
}
|
||
else
|
||
{
|
||
valueCell.SetCellValue("");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
valueCell.SetCellValue("");
|
||
}
|
||
valueCell.CellStyle = styles.yellowStyle;
|
||
|
||
// 为合并区域的其他单元格设置样式
|
||
for (int i = 2; i <= sampleCount; i++)
|
||
{
|
||
row.CreateCell(i).CellStyle = styles.yellowStyle;
|
||
}
|
||
// 合并单元格
|
||
sheet.AddMergedRegion(new CellRangeAddress(currentRow - 1, currentRow - 1, 1, sampleCount));
|
||
}
|
||
else
|
||
{
|
||
// 普通数据行,显示每个试样的数据
|
||
for (int i = 1; i <= sampleCount; i++)
|
||
{
|
||
ICell cell = row.CreateCell(i);
|
||
if (dataTable.Columns.Contains($"试样{i}") && dataRow[$"试样{i}"] != DBNull.Value)
|
||
{
|
||
object value = dataRow[$"试样{i}"];
|
||
if (value != null)
|
||
{
|
||
// 尝试转换为 double
|
||
if (double.TryParse(value.ToString(), out double numValue))
|
||
{
|
||
cell.SetCellValue(numValue);
|
||
}
|
||
else
|
||
{
|
||
// 如果不是数字,直接显示字符串值
|
||
cell.SetCellValue(value.ToString());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
cell.SetCellValue("");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
cell.SetCellValue("");
|
||
}
|
||
cell.CellStyle = styles.yellowStyle;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private void CreateForm3Section(ISheet sheet, ref int currentRow, int sampleCount, DataTable dataTable,
|
||
(ICellStyle titleStyle, ICellStyle headerStyle, ICellStyle dataStyle, ICellStyle yellowStyle) styles)
|
||
{
|
||
// 子标题
|
||
IRow subtitleRow = sheet.CreateRow(currentRow++);
|
||
subtitleRow.Height = 500;
|
||
ICell subtitleCell = subtitleRow.CreateCell(0);
|
||
subtitleCell.SetCellValue("液体芯吸速率");
|
||
subtitleCell.CellStyle = styles.headerStyle;
|
||
// 为合并区域的所有单元格设置样式
|
||
for (int i = 1; i <= sampleCount * 3; i++)
|
||
{
|
||
subtitleRow.CreateCell(i).CellStyle = styles.headerStyle;
|
||
}
|
||
sheet.AddMergedRegion(new CellRangeAddress(currentRow - 1, currentRow - 1, 0, sampleCount * 3));
|
||
|
||
// 第一行表头(纵向/横向)
|
||
IRow headerRow1 = sheet.CreateRow(currentRow);
|
||
headerRow1.Height = 400;
|
||
ICell seqCell1 = headerRow1.CreateCell(0);
|
||
seqCell1.SetCellValue("序号");
|
||
seqCell1.CellStyle = styles.headerStyle;
|
||
|
||
ICell dirCell = headerRow1.CreateCell(1);
|
||
dirCell.SetCellValue("纵向/横向(选择按钮)");
|
||
dirCell.CellStyle = styles.headerStyle;
|
||
// 为合并区域的所有单元格设置样式
|
||
for (int i = 2; i <= sampleCount * 3; i++)
|
||
{
|
||
headerRow1.CreateCell(i).CellStyle = styles.headerStyle;
|
||
}
|
||
sheet.AddMergedRegion(new CellRangeAddress(currentRow, currentRow, 1, sampleCount * 3));
|
||
|
||
currentRow++;
|
||
|
||
// 第二行表头(试样1-N,每个3列)
|
||
IRow headerRow2 = sheet.CreateRow(currentRow);
|
||
headerRow2.Height = 400;
|
||
|
||
// 序号列在第二行也需要创建并设置样式(用于合并)
|
||
headerRow2.CreateCell(0).CellStyle = styles.headerStyle;
|
||
|
||
int colIndex = 1;
|
||
for (int i = 1; i <= sampleCount; i++)
|
||
{
|
||
ICell cell = headerRow2.CreateCell(colIndex);
|
||
cell.SetCellValue($"试样{i}");
|
||
cell.CellStyle = styles.headerStyle;
|
||
// 为合并区域的所有单元格设置样式
|
||
headerRow2.CreateCell(colIndex + 1).CellStyle = styles.headerStyle;
|
||
headerRow2.CreateCell(colIndex + 2).CellStyle = styles.headerStyle;
|
||
sheet.AddMergedRegion(new CellRangeAddress(currentRow, currentRow, colIndex, colIndex + 2));
|
||
colIndex += 3;
|
||
}
|
||
|
||
// 合并序号列(跨两行)
|
||
sheet.AddMergedRegion(new CellRangeAddress(currentRow - 1, currentRow, 0, 0));
|
||
|
||
currentRow++;
|
||
|
||
// 第三行表头(1、2、3)
|
||
IRow headerRow3 = sheet.CreateRow(currentRow++);
|
||
headerRow3.Height = 400;
|
||
|
||
colIndex = 1;
|
||
for (int i = 1; i <= sampleCount; i++)
|
||
{
|
||
for (int j = 1; j <= 3; j++)
|
||
{
|
||
ICell cell = headerRow3.CreateCell(colIndex++);
|
||
cell.SetCellValue(j.ToString());
|
||
cell.CellStyle = styles.headerStyle;
|
||
}
|
||
}
|
||
|
||
// 数据行
|
||
if (dataTable != null && dataTable.Rows.Count > 0)
|
||
{
|
||
foreach (DataRow dataRow in dataTable.Rows)
|
||
{
|
||
string rowName = dataRow["序号"]?.ToString() ?? "";
|
||
if (string.IsNullOrEmpty(rowName)) continue;
|
||
|
||
IRow row = sheet.CreateRow(currentRow++);
|
||
row.Height = 380;
|
||
|
||
ICell nameCell = row.CreateCell(0);
|
||
nameCell.SetCellValue(rowName);
|
||
nameCell.CellStyle = styles.dataStyle;
|
||
|
||
// 判断是否是标准偏差行(需要合并为一列)
|
||
bool isStdDeviationRow = rowName.Contains("标准偏差");
|
||
|
||
if (isStdDeviationRow)
|
||
{
|
||
// 标准偏差行:合并为一列,只显示第一个值
|
||
ICell valueCell = row.CreateCell(1);
|
||
string columnName = "试样1_1";
|
||
if (dataTable.Columns.Contains(columnName) && dataRow[columnName] != DBNull.Value)
|
||
{
|
||
if (double.TryParse(dataRow[columnName].ToString(), out double value))
|
||
{
|
||
if (Math.Abs(value) >= 0.001)
|
||
{
|
||
valueCell.SetCellValue(value);
|
||
}
|
||
else
|
||
{
|
||
valueCell.SetCellValue("");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
valueCell.SetCellValue("");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
valueCell.SetCellValue("");
|
||
}
|
||
valueCell.CellStyle = styles.yellowStyle;
|
||
|
||
// 为合并区域的其他单元格设置样式
|
||
for (int i = 2; i <= sampleCount * 3; i++)
|
||
{
|
||
row.CreateCell(i).CellStyle = styles.yellowStyle;
|
||
}
|
||
// 合并单元格
|
||
sheet.AddMergedRegion(new CellRangeAddress(currentRow - 1, currentRow - 1, 1, sampleCount * 3));
|
||
}
|
||
else
|
||
{
|
||
// 普通数据行:显示每个试样的每次测试数据
|
||
colIndex = 1;
|
||
for (int i = 1; i <= sampleCount; i++)
|
||
{
|
||
for (int j = 1; j <= 3; j++)
|
||
{
|
||
ICell cell = row.CreateCell(colIndex++);
|
||
string columnName = $"试样{i}_{j}";
|
||
|
||
if (dataTable.Columns.Contains(columnName) && dataRow[columnName] != DBNull.Value)
|
||
{
|
||
if (double.TryParse(dataRow[columnName].ToString(), out double value))
|
||
{
|
||
if (Math.Abs(value) >= 0.001)
|
||
{
|
||
cell.SetCellValue(value);
|
||
}
|
||
else
|
||
{
|
||
// 所有空数据都显示为空白
|
||
cell.SetCellValue("");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 所有空数据都显示为空白
|
||
cell.SetCellValue("");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 所有空数据都显示为空白
|
||
cell.SetCellValue("");
|
||
}
|
||
cell.CellStyle = styles.yellowStyle;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
||
{
|
||
clockTimer?.Stop();
|
||
clockTimer?.Dispose();
|
||
Application.Exit();
|
||
}
|
||
|
||
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;
|
||
titleStyle.VerticalAlignment = VerticalAlignment.Center;
|
||
|
||
// 表头样式(灰色背景)
|
||
ICellStyle headerStyle = workbook.CreateCellStyle();
|
||
headerStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;
|
||
headerStyle.FillPattern = FillPattern.SolidForeground;
|
||
SetBorders(headerStyle);
|
||
IFont headerFont = workbook.CreateFont();
|
||
headerFont.IsBold = true;
|
||
headerStyle.SetFont(headerFont);
|
||
headerStyle.Alignment = NPOIHorizontalAlignment.Center;
|
||
headerStyle.VerticalAlignment = VerticalAlignment.Center;
|
||
|
||
// 数据样式(白色背景)
|
||
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 (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;
|
||
}
|
||
}
|
||
}
|