using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.SS.Util; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApp6 { public partial class AbsorbTestReportControl : UserControl { // 报告头控件(手动录入/系统填充项) private Label lblTitle; private Label lblSampleName, lblMaterialCode, lblBatch, lblOperator; private Label lblTestTime, lblInstrument, lblDeviceNo, lblDataFile; public TextBox txtSampleName, txtMaterialCode, txtBatch, txtOperator; public TextBox txtTestTime, txtInstrument, txtDeviceNo, txtDataFile; // 液体吸收时间表 private DataGridView dgvAbsorbTime; private Label lblAbsorbTitle; public AbsorbTestReportControl() { // 2. 仅保留设计器自动生成的InitializeComponent调用 // 手动初始化逻辑移到BuildReportLayout方法 InitializeComponent(); BuildReportLayout(); // 构建完整报告布局 } // 构建报告头+表格的完整布局 private void BuildReportLayout() { // 清空原有控件(避免重复加载) this.Controls.Clear(); // 1. 报告标题(适配控件宽度) lblTitle = new Label { Text = "吸收性测试报告", Font = new Font("微软雅黑", 12, FontStyle.Bold), AutoSize = false, Size = new Size(this.ClientSize.Width - 20, 30), // 适配控件宽度 TextAlign = ContentAlignment.MiddleCenter, Location = new Point(10, 10) // 留边距,避免超出控件范围 }; this.Controls.Add(lblTitle); // 2. 报告头信息区域(优化坐标,避免超出范围) int headerY = 50; int labelWidth = 80, txtWidth = 120, gap = 10; // 限制每行控件总宽度,避免超出控件范围 int maxRowWidth = this.ClientSize.Width - 40; // 第一行:样品名称、物料编码(如果宽度不够,拆行显示) lblSampleName = new Label { Text = "样品名称1:", Location = new Point(10, headerY), Size = new Size(labelWidth, 20) }; txtSampleName = new TextBox { Text = "手动录入", Location = new Point(lblSampleName.Right + gap, headerY), Size = new Size(txtWidth, 20) }; lblMaterialCode = new Label { Text = "物料编码:", Location = new Point(txtSampleName.Right + gap * 2, headerY), Size = new Size(labelWidth, 20) }; txtMaterialCode = new TextBox { Text = "手动录入", Location = new Point(lblMaterialCode.Right + gap, headerY), Size = new Size(txtWidth, 20) }; // 第二列:批号、操作人员(拆行,避免宽度不足) headerY += 30; lblBatch = new Label { Text = "批号:", Location = new Point(10, headerY), Size = new Size(labelWidth, 20) }; txtBatch = new TextBox { Text = "手动录入", Location = new Point(lblBatch.Right + gap, headerY), Size = new Size(txtWidth, 20) }; lblOperator = new Label { Text = "操作人员:", Location = new Point(txtBatch.Right + gap * 2, headerY), Size = new Size(labelWidth, 20) }; txtOperator = new TextBox { Text = "手动录入", Location = new Point(lblOperator.Right + gap, headerY), Size = new Size(txtWidth, 20) }; // 第三行:测试时间、仪器 headerY += 30; lblTestTime = new Label { Text = "测试时间:", Location = new Point(10, headerY), Size = new Size(labelWidth, 20) }; txtTestTime = new TextBox { Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), BackColor = Color.Yellow, Location = new Point(lblTestTime.Right + gap, headerY), Size = new Size(txtWidth + 30, 20) }; lblInstrument = new Label { Text = "仪器:", Location = new Point(txtTestTime.Right + gap * 2, headerY), Size = new Size(labelWidth, 20) }; txtInstrument = new TextBox { Text = "厂家仪器名称", BackColor = Color.Yellow, Location = new Point(lblInstrument.Right + gap, headerY), Size = new Size(txtWidth + 30, 20) }; // 第四行:设备编号、数据文件 headerY += 30; lblDeviceNo = new Label { Text = "设备编号:", Location = new Point(10, headerY), Size = new Size(labelWidth, 20) }; txtDeviceNo = new TextBox { Text = "手动录入", Location = new Point(lblDeviceNo.Right + gap, headerY), Size = new Size(txtWidth + 30, 20) }; lblDataFile = new Label { Text = "数据文件:", Location = new Point(txtDeviceNo.Right + gap * 2, headerY), Size = new Size(labelWidth, 20) }; txtDataFile = new TextBox { Text = "(报告保存路径)", Location = new Point(lblDataFile.Right + gap, headerY), Size = new Size(txtWidth + 50, 20) }; // 将报告头控件添加到容器 this.Controls.AddRange(new Control[] { lblSampleName, txtSampleName, lblMaterialCode, txtMaterialCode, lblBatch, txtBatch, lblOperator, txtOperator, lblTestTime, txtTestTime, lblInstrument, txtInstrument, lblDeviceNo, txtDeviceNo, lblDataFile, txtDataFile }); // 3. 液体吸收时间表区域(关键:适配控件宽度) int tableY = headerY + 40; lblAbsorbTitle = new Label { Text = "液体吸收时间", Location = new Point(10, tableY), Size = new Size(100, 20), Font = new Font("微软雅黑", 9, FontStyle.Bold) }; // 初始化表格(适配控件宽度和高度) dgvAbsorbTime = new DataGridView { Location = new Point(10, tableY + 25), // 表格宽度=控件宽度-20,高度=控件高度-tableY-50(避免超出) Size = new Size(this.ClientSize.Width - 20, this.ClientSize.Height - tableY - 50), BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle, AllowUserToAddRows = false, ReadOnly = false, RowHeadersVisible = false, AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill // 列自动填充宽度 }; // 添加表格列 dgvAbsorbTime.Columns.Add("colSeq", "序号"); dgvAbsorbTime.Columns.Add("colTime", "时间, S"); dgvAbsorbTime.Columns.Add("colAvgTime", "平均时间, S"); dgvAbsorbTime.Columns.Add("colTip", ""); // 填充默认行+黄色高亮 AddSampleRow("试样1"); AddSampleRow("试样2"); dgvAbsorbTime.Rows[0].Cells["colTip"].Value = "根据样品个数进行递增"; this.Controls.AddRange(new Control[] { lblAbsorbTitle, dgvAbsorbTime }); } // 对外方法:添加试样行 public void AddSampleRow(string sampleName) { int rowIdx = dgvAbsorbTime.Rows.Add(sampleName); // 设置时间/平均时间单元格为黄色高亮 DataGridViewCellStyle highlightStyle = new DataGridViewCellStyle { BackColor = Color.Yellow }; dgvAbsorbTime.Rows[rowIdx].Cells["colTime"].Style = highlightStyle; dgvAbsorbTime.Rows[rowIdx].Cells["colAvgTime"].Style = highlightStyle; } // 对外方法:导出完整报告(包含头信息+表格) public void ExportFullReport(string savePath) { HSSFWorkbook workbook = new HSSFWorkbook(); ISheet sheet = workbook.CreateSheet("吸收性测试报告"); int rowIdx = 0; // 1. 导出报告标题 IRow titleRow = sheet.CreateRow(rowIdx++); titleRow.CreateCell(0).SetCellValue("吸收性测试报告"); sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, 5)); // 合并单元格 // 2. 导出报告头信息 IRow row1 = sheet.CreateRow(rowIdx++); row1.CreateCell(0).SetCellValue("样品名称1:"); row1.CreateCell(1).SetCellValue(txtSampleName.Text); row1.CreateCell(2).SetCellValue("物料编码:"); row1.CreateCell(3).SetCellValue(txtMaterialCode.Text); row1.CreateCell(4).SetCellValue("批号:"); row1.CreateCell(5).SetCellValue(txtBatch.Text); row1.CreateCell(6).SetCellValue("操作人员:"); row1.CreateCell(7).SetCellValue(txtOperator.Text); IRow row2 = sheet.CreateRow(rowIdx++); row2.CreateCell(0).SetCellValue("测试时间:"); row2.CreateCell(1).SetCellValue(txtTestTime.Text); row2.CreateCell(2).SetCellValue("仪器:"); row2.CreateCell(3).SetCellValue(txtInstrument.Text); row2.CreateCell(4).SetCellValue("设备编号:"); row2.CreateCell(5).SetCellValue(txtDeviceNo.Text); row2.CreateCell(6).SetCellValue("数据文件:"); row2.CreateCell(7).SetCellValue(txtDataFile.Text); // 3. 导出液体吸收时间表 rowIdx++; // 空行分隔 IRow tableTitleRow = sheet.CreateRow(rowIdx++); tableTitleRow.CreateCell(0).SetCellValue("液体吸收时间"); IRow tableHeaderRow = sheet.CreateRow(rowIdx++); tableHeaderRow.CreateCell(0).SetCellValue("序号"); tableHeaderRow.CreateCell(1).SetCellValue("时间, S"); tableHeaderRow.CreateCell(2).SetCellValue("平均时间, S"); foreach (DataGridViewRow dgvRow in dgvAbsorbTime.Rows) { IRow dataRow = sheet.CreateRow(rowIdx++); dataRow.CreateCell(0).SetCellValue(dgvRow.Cells["colSeq"].Value?.ToString() ?? ""); dataRow.CreateCell(1).SetCellValue(dgvRow.Cells["colTime"].Value?.ToString() ?? ""); dataRow.CreateCell(2).SetCellValue(dgvRow.Cells["colAvgTime"].Value?.ToString() ?? ""); } // 保存Excel using (FileStream fs = new FileStream(savePath, FileMode.Create)) { workbook.Write(fs); } } } }