using AciTester.Models; using OfficeOpenXml; using System.ComponentModel; using System.IO; using System.Threading.Tasks; namespace AciTester.Services { public class ExcelReportService : IReportService { public async Task GenerateReportAsync(TestResult result, string filePath) { ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial; using var package = new ExcelPackage(); var sheet = package.Workbook.Worksheets.Add("ACI测试报告"); // 标题 sheet.Cells["A1"].Value = "中国药典2025版四部通则0951装置3测试报告"; sheet.Cells["A1:C1"].Merge = true; sheet.Cells["A1"].Style.Font.Bold = true; sheet.Cells["A1"].Style.Font.Size = 16; // 基本信息 sheet.Cells["A3"].Value = "测试时间:"; sheet.Cells["B3"].Value = result.TestTime.ToString("yyyy-MM-dd HH:mm:ss"); sheet.Cells["A4"].Value = "采样流量(L/min):"; sheet.Cells["B4"].Value = result.FlowRate; sheet.Cells["A5"].Value = "总质量F(g):"; sheet.Cells["B5"].Value = result.TotalMass; // 测试环境 sheet.Cells["A6"].Value = "测试环境:"; sheet.Cells["B6"].Value = $"流量: {result.FlowRate:F2} L/min, 温度: {result.Temperature:F1}℃, 压差: {result.DifferentialPressure:F2} kPa"; // 微细粒子指标 sheet.Cells["A7"].Value = "微细粒子剂量(FPD)"; sheet.Cells["B7"].Value = $"{result.FineParticleDose:F2} mg"; sheet.Cells["A8"].Value = "微细粒子分数(FPF)"; sheet.Cells["B8"].Value = $"{result.FineParticleFraction:F2}%"; // ============ 新增:粒径分布参数 ============ sheet.Cells["A9"].Value = "粒径分布参数"; sheet.Cells["A9"].Style.Font.Bold = true; sheet.Cells["A10"].Value = "D10 (μm)"; sheet.Cells["B10"].Value = result.D10; sheet.Cells["A11"].Value = "D50 (μm) (MMAD)"; sheet.Cells["B11"].Value = result.D50; sheet.Cells["A12"].Value = "D90 (μm)"; sheet.Cells["B12"].Value = result.D90; sheet.Cells["A13"].Value = "GSD (几何标准偏差)"; sheet.Cells["B13"].Value = result.GSD; // 各级数据表(起始行号调整为15) int dataStartRow = 15; sheet.Cells[dataStartRow, 1].Value = "层级"; sheet.Cells[dataStartRow, 2].Value = "截止直径(μm)"; sheet.Cells[dataStartRow, 3].Value = "净重(g)"; sheet.Cells[dataStartRow, 4].Value = "占比(%)"; sheet.Cells[dataStartRow, 1, dataStartRow, 4].Style.Font.Bold = true; int row = dataStartRow + 1; double total = result.TotalMass; foreach (var stage in result.Stages) { double percent = total > 0 ? stage.NetWeight / total * 100 : 0; sheet.Cells[row, 1].Value = stage.StageName; sheet.Cells[row, 2].Value = stage.CutoffDiameter > 0 ? stage.CutoffDiameter.ToString("F1") : "—"; sheet.Cells[row, 3].Value = stage.NetWeight; sheet.Cells[row, 4].Value = percent.ToString("F2"); row++; } sheet.Cells.AutoFitColumns(); await package.SaveAsAsync(new FileInfo(filePath)); } } }