From 915fbdaa11baa6b027d09ce71b10e73590389149 Mon Sep 17 00:00:00 2001 From: xyy <544939200@qq.com> Date: Thu, 4 Jun 2026 14:28:07 +0800 Subject: [PATCH] --- ASTM D7896-19瞬态热线法.csproj | 1 + ViewModels/D7896ViewModel.cs | 176 +++++++++++++++++++++++++++++---- 2 files changed, 158 insertions(+), 19 deletions(-) diff --git a/ASTM D7896-19瞬态热线法.csproj b/ASTM D7896-19瞬态热线法.csproj index 8b5e8a8..49c2cd2 100644 --- a/ASTM D7896-19瞬态热线法.csproj +++ b/ASTM D7896-19瞬态热线法.csproj @@ -22,6 +22,7 @@ + diff --git a/ViewModels/D7896ViewModel.cs b/ViewModels/D7896ViewModel.cs index 3d09b2a..acb1ec5 100644 --- a/ViewModels/D7896ViewModel.cs +++ b/ViewModels/D7896ViewModel.cs @@ -6,6 +6,9 @@ using CommunityToolkit.Mvvm.Input; using OxyPlot; using OxyPlot.Axes; using OxyPlot.Series; +using OxyPlot.Wpf; +using PdfSharpCore.Drawing; +using PdfSharpCore.Pdf; using System; using System.Collections.ObjectModel; using System.IO; @@ -806,6 +809,40 @@ public partial class D7896ViewModel : ObservableObject TemperatureCurveModel = null; } + //[RelayCommand] + //private async Task GenerateReportAsync() + //{ + // if (Measurements.Count == 0) + // { + // MessageBox.Show("没有测试数据", "提示"); + // return; + // } + // try + // { + // var extraParams = new Dictionary + // { + // ["SampleVolume"] = SampleVolume, + // ["BubbleRemoved"] = BubbleRemoved, + // ["UsePressure"] = UsePressure, + // ["PressureValue"] = PressureValue, + // ["IsCleanConfirmed"] = IsCleanConfirmed, + // ["CleanerName"] = CleanerName, + // ["AmbientTemperature"] = AmbientTemperature, + // ["AmbientCalibrated"] = AmbientCalibrated, + // ["PlatinumCompatible"] = PlatinumCompatible, + // ["LiquidReactivityNote"] = LiquidReactivityNote, + // ["InitialResistance"] = PlatinumResistance + // }; + // string reportPath = await _reportService.GenerateReportAsync(SampleId, TestTemperature, Measurements.ToList(), + // AverageThermalConductivity, AverageThermalDiffusivity, AverageVolumetricHeatCapacity, + // _config.TestParameters, extraParams); + // MessageBox.Show($"报告已生成: {reportPath}", "成功"); + // } + // catch (Exception ex) + // { + // MessageBox.Show($"生成报告失败: {ex.Message}", "错误"); + // } + //} [RelayCommand] private async Task GenerateReportAsync() { @@ -814,35 +851,136 @@ public partial class D7896ViewModel : ObservableObject MessageBox.Show("没有测试数据", "提示"); return; } + + // 选择保存路径 + var saveFileDialog = new Microsoft.Win32.SaveFileDialog + { + Filter = "PDF files (*.pdf)|*.pdf", + DefaultExt = ".pdf", + FileName = $"报告_{SampleId}_{DateTime.Now:yyyyMMdd_HHmmss}.pdf" + }; + if (saveFileDialog.ShowDialog() != true) + return; + + string pdfPath = saveFileDialog.FileName; + try { - var extraParams = new Dictionary - { - ["SampleVolume"] = SampleVolume, - ["BubbleRemoved"] = BubbleRemoved, - ["UsePressure"] = UsePressure, - ["PressureValue"] = PressureValue, - ["IsCleanConfirmed"] = IsCleanConfirmed, - ["CleanerName"] = CleanerName, - ["AmbientTemperature"] = AmbientTemperature, - ["AmbientCalibrated"] = AmbientCalibrated, - ["PlatinumCompatible"] = PlatinumCompatible, - ["LiquidReactivityNote"] = LiquidReactivityNote, - ["InitialResistance"] = PlatinumResistance - }; - string reportPath = await _reportService.GenerateReportAsync(SampleId, TestTemperature, Measurements.ToList(), - AverageThermalConductivity, AverageThermalDiffusivity, AverageVolumetricHeatCapacity, - _config.TestParameters, extraParams); - MessageBox.Show($"报告已生成: {reportPath}", "成功"); + // 生成 PDF + await Task.Run(() => GeneratePdfReport(pdfPath)); + MessageBox.Show($"报表已生成: {pdfPath}", "成功"); } catch (Exception ex) { - MessageBox.Show($"生成报告失败: {ex.Message}", "错误"); + MessageBox.Show($"生成报表失败: {ex.Message}", "错误"); } } + + private void GeneratePdfReport(string filePath) + { + // 1. 创建文档 + using (var document = new PdfDocument()) + { + // 2. 添加页面 + var page = document.AddPage(); + page.Width = XUnit.FromMillimeter(210); + page.Height = XUnit.FromMillimeter(297); + + // 3. 开始绘制 + using (var gfx = XGraphics.FromPdfPage(page)) + { + // 创建字体 + var titleFont = new XFont("Verdana", 16, XFontStyle.Bold); + var headerFont = new XFont("Verdana", 12, XFontStyle.Bold); + var normalFont = new XFont("Verdana", 10, XFontStyle.Regular); + double yPosition = 30; + + // ---------- 4. 添加标题 ---------- + gfx.DrawString("ASTM D7896-19 瞬态热线法测试报告", titleFont, XBrushes.Black, + new XRect(0, yPosition, page.Width, 30), XStringFormats.TopCenter); + yPosition += 40; + + // ---------- 5. 添加基础信息 ---------- + gfx.DrawString($"样品名称: {SampleId}", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 25; + gfx.DrawString($"测试温度: {TestTemperature:F1} °C", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 25; + // ... 所有需要显示的基础信息 + + yPosition += 10; + + // ---------- 6. 插入温升曲线图 ---------- + if (TemperatureCurveModel != null) + { + using (var stream = new MemoryStream()) + { + var exporter = new PngExporter { Width = 600, Height = 400 }; + exporter.Export(TemperatureCurveModel, stream); + stream.Position = 0; + var imgStream = new MemoryStream(stream.ToArray(), 0, (int)stream.Length, false, true); + var image = XImage.FromStream(() => imgStream); + gfx.DrawImage(image, 40, yPosition, 500, 330); + yPosition += 350; + } + } + + // ---------- 7. 创建表格 ---------- + gfx.DrawString("测量结果明细", headerFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 25; + + // 表头 + string[] headers = { "序号", "热导率λ(W/(m·K))", "热扩散率α(10⁻⁷ m²/s)", "体积热容VHC(kJ/(m³·K))", "比热容Cp(J/(kg·K))" }; + double[] colWidths = { 50, 100, 100, 120, 100 }; + double startX = 40; + double currentRowY = yPosition; + + // 绘制表头 + for (int i = 0; i < headers.Length; i++) + { + double cellX = startX + colWidths.Take(i).Sum(); + gfx.DrawRectangle(XPens.Black, cellX, currentRowY, colWidths[i], 20); + var textRect = new XRect(cellX, currentRowY, colWidths[i], 20); + gfx.DrawString(headers[i], normalFont, XBrushes.Black, textRect, XStringFormats.Center); + } + currentRowY += 20; + + // 填充数据行 (假设 Measurements 是列表) + for (int i = 0; i < Measurements.Count; i++) + { + var m = Measurements[i]; + string[] rowData = { + m.Index.ToString(), + m.ThermalConductivity.ToString("F6"), + (m.ThermalDiffusivity * 1e7).ToString("F3"), + m.VolumetricHeatCapacity.ToString("F2"), + m.SpecificHeatCapacity.ToString("F2") + }; + + for (int j = 0; j < rowData.Length; j++) + { + double cellX = startX + colWidths.Take(j).Sum(); + gfx.DrawRectangle(XPens.Black, cellX, currentRowY, colWidths[j], 20); + var textRect = new XRect(cellX, currentRowY, colWidths[j], 20); + gfx.DrawString(rowData[j], normalFont, XBrushes.Black, textRect, XStringFormats.Center); + } + currentRowY += 20; + } + yPosition = currentRowY + 10; + + // ---------- 8. 添加平均值 ---------- + gfx.DrawString($"平均热导率: {AverageThermalConductivity:F6} W/(m·K)", normalFont, XBrushes.Black, new XPoint(40, yPosition)); yPosition += 20; + // ... 其他平均值 + + // ---------- 9. 添加生成时间和页脚 ---------- + gfx.DrawString($"生成时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}", normalFont, XBrushes.Black, new XPoint(40, page.Height - 30)); + } + + // 10. 保存文档 + document.Save(filePath); + } + } + + [RelayCommand] private async Task StopTest() {