This commit is contained in:
xyy
2026-03-24 21:05:32 +08:00
parent 9437c6010a
commit 01a07f8811
26 changed files with 7 additions and 2387 deletions

View File

@@ -1,54 +0,0 @@
using OfficeOpenXml;
using System.IO;
public static class ExportHelper
{
public static void ExportBubblePoint(BubblePointEntity entity, string filePath)
{
using var package = new ExcelPackage();
var sheet = package.Workbook.Worksheets.Add("泡点法测试");
sheet.Cells["A1"].Value = "工位"; sheet.Cells["B1"].Value = entity.StationId;
sheet.Cells["A2"].Value = "测试日期"; sheet.Cells["B2"].Value = entity.TestDate.ToString("yyyy-MM-dd HH:mm:ss");
sheet.Cells["A3"].Value = "测试者"; sheet.Cells["B3"].Value = entity.Tester;
sheet.Cells["A4"].Value = "样品类型"; sheet.Cells["B4"].Value = entity.SampleType;
sheet.Cells["A5"].Value = "规格"; sheet.Cells["B5"].Value = entity.SampleSpec;
sheet.Cells["A6"].Value = "室温(°C)"; sheet.Cells["B6"].Value = entity.RoomTemperature;
sheet.Cells["A7"].Value = "浸润时间(h)"; sheet.Cells["B7"].Value = entity.SoakingTime;
sheet.Cells["A8"].Value = "测试液体"; sheet.Cells["B8"].Value = entity.LiquidName;
sheet.Cells["A9"].Value = "液体生产厂家"; sheet.Cells["B9"].Value = entity.LiquidManufacturer;
sheet.Cells["A10"].Value = "泡点压力"; sheet.Cells["B10"].Value = $"{entity.BubblePointPressure} {entity.PressureUnit}";
sheet.Cells["A11"].Value = "最大孔径(μm)"; sheet.Cells["B11"].Value = entity.MaxPoreSize;
package.SaveAs(new FileInfo(filePath));
}
public static void ExportPoreDistribution(PoreDistributionEntity entity, string filePath)
{
using var package = new ExcelPackage();
var sheet = package.Workbook.Worksheets.Add("孔分布测试");
sheet.Cells["A1"].Value = "工位"; sheet.Cells["B1"].Value = entity.StationId;
sheet.Cells["A2"].Value = "测试日期"; sheet.Cells["B2"].Value = entity.TestDate.ToString("yyyy-MM-dd HH:mm:ss");
sheet.Cells["A3"].Value = "测试者"; sheet.Cells["B3"].Value = entity.Tester;
sheet.Cells["A4"].Value = "样品类型"; sheet.Cells["B4"].Value = entity.SampleType;
sheet.Cells["A5"].Value = "规格"; sheet.Cells["B5"].Value = entity.SampleSpec;
sheet.Cells["A6"].Value = "室温(°C)"; sheet.Cells["B6"].Value = entity.RoomTemperature;
sheet.Cells["A7"].Value = "浸润时间(h)"; sheet.Cells["B7"].Value = entity.SoakingTime;
sheet.Cells["A8"].Value = "测试液体"; sheet.Cells["B8"].Value = entity.LiquidName;
sheet.Cells["A9"].Value = "液体生产厂家"; sheet.Cells["B9"].Value = entity.LiquidManufacturer;
sheet.Cells["A10"].Value = "泡点压力"; sheet.Cells["B10"].Value = $"{entity.BubblePointPressure} {entity.PressureUnit}";
sheet.Cells["A11"].Value = "平均孔径(μm)"; sheet.Cells["B11"].Value = entity.AveragePoreSize;
// 数据点表格
sheet.Cells["A13"].Value = "压力"; sheet.Cells["B13"].Value = "湿膜流量(L/min)"; sheet.Cells["C13"].Value = "干膜流量(L/min)";
int row = 14;
foreach (var dp in entity.DataPoints)
{
sheet.Cells[$"A{row}"].Value = dp.Pressure;
sheet.Cells[$"B{row}"].Value = dp.WetFlow;
sheet.Cells[$"C{row}"].Value = dp.DryFlow;
row++;
}
package.SaveAs(new FileInfo(filePath));
}
}

View File

@@ -73,6 +73,7 @@
Task<ushort[]> ReadHoldingRegistersAsync(ushort startAddress, ushort count);
Task WriteSingleRegisterAsync(ushort registerAddress, ushort value);
}

View File

@@ -1,31 +0,0 @@
using MembranePoreTester.Models;
namespace MembranePoreTester.Helpers
{
public static class PoreCalculator
{
public static double PressureToPore(double pressure, string unit, TestLiquid liquid)
{
if (liquid == null) return 0;
return unit switch
{
"Pa" => liquid.C_Pa / pressure,
"cmHg" => liquid.C_cmHg / pressure,
"psi" => liquid.C_psi / pressure,
_ => 0
};
}
public static double PoreToPressure(double pore, string unit, TestLiquid liquid)
{
if (liquid == null) return 0;
return unit switch
{
"Pa" => liquid.C_Pa / pore,
"cmHg" => liquid.C_cmHg / pore,
"psi" => liquid.C_psi / pore,
_ => 0
};
}
}
}

View File

@@ -1,69 +0,0 @@
using MembranePoreTester.Models;
using System.Collections.Generic;
using System.Linq;
namespace MembranePoreTester.Helpers
{
public static class PoreDistributionAnalysis
{
public static double CalculateAveragePore(
IEnumerable<DataPoint> points,
string unit,
TestLiquid liquid)
{
var sorted = points.OrderBy(p => p.Pressure).ToList();
if (sorted.Count < 2) return 0;
double[] pressures = sorted.Select(p => p.Pressure).ToArray();
double[] dryFlows = sorted.Select(p => p.DryFlow).ToArray();
double[] wetFlows = sorted.Select(p => p.WetFlow).ToArray();
double halfDryFlow = dryFlows.Max() / 2.0;
// 找到湿膜流量等于 halfDryFlow 的压力(交点)
for (int i = 0; i < wetFlows.Length - 1; i++)
{
if ((wetFlows[i] <= halfDryFlow && wetFlows[i + 1] >= halfDryFlow) ||
(wetFlows[i] >= halfDryFlow && wetFlows[i + 1] <= halfDryFlow))
{
double p = Interpolation.Linear(
new[] { wetFlows[i], wetFlows[i + 1] },
new[] { pressures[i], pressures[i + 1] },
halfDryFlow);
return PoreCalculator.PressureToPore(p, unit, liquid);
}
}
return 0;
}
public static double CalculatePoreRangePercentage(
IEnumerable<DataPoint> points,
string unit,
TestLiquid liquid,
double lowerPore,
double upperPore)
{
var sorted = points.OrderBy(p => p.Pressure).ToList();
if (sorted.Count < 2) return 0;
double[] pressures = sorted.Select(p => p.Pressure).ToArray();
double[] wetFlows = sorted.Select(p => p.WetFlow).ToArray();
double[] dryFlows = sorted.Select(p => p.DryFlow).ToArray();
// 大孔径对应低压,小孔径对应高压
double pLower = PoreCalculator.PoreToPressure(upperPore, unit, liquid);
double pUpper = PoreCalculator.PoreToPressure(lowerPore, unit, liquid);
// 插值
double qWetLower = Interpolation.Linear(pressures, wetFlows, pLower);
double qDryLower = Interpolation.Linear(pressures, dryFlows, pLower);
double qWetUpper = Interpolation.Linear(pressures, wetFlows, pUpper);
double qDryUpper = Interpolation.Linear(pressures, dryFlows, pUpper);
double ratioLow = qWetLower / qDryLower;
double ratioHigh = qWetUpper / qDryUpper;
return (ratioHigh - ratioLow) * 100;
}
}
}

View File

@@ -1,227 +0,0 @@
using MembranePoreTester.Models;
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Xps.Packaging;
namespace MembranePoreTester.Helpers
{
public static class ReportGenerator
{
public static void GenerateBubblePointReport(BubblePointRecord record)
{
FlowDocument doc = CreateBubblePointDocument(record);
ShowPrintPreview(doc, "泡点法测试报告");
}
public static void GeneratePoreDistributionReport(PoreDistributionRecord record)
{
FlowDocument doc = CreatePoreDistributionDocument(record);
ShowPrintPreview(doc, "孔分布测试报告");
}
private static FlowDocument CreateBubblePointDocument(BubblePointRecord record)
{
FlowDocument doc = new FlowDocument();
doc.PageWidth = 800; // 适应打印
// 标题
doc.Blocks.Add(new Paragraph(new Run("泡点法测试报告"))
{
FontSize = 24,
FontWeight = FontWeights.Bold,
TextAlignment = TextAlignment.Center
});
// 日期/测试者
doc.Blocks.Add(new Paragraph(new Run($"测试日期: {record.TestDate:yyyy-MM-dd} 测试者: {record.Tester}"))
{
TextAlignment = TextAlignment.Right
});
// 样品信息表格
Table table = new Table();
table.Columns.Add(new TableColumn { Width = new GridLength(150) });
table.Columns.Add(new TableColumn { Width = new GridLength(200) });
TableRowGroup group = new TableRowGroup();
AddRow(group, "膜类型", record.SampleType);
AddRow(group, "规格", record.SampleSpec);
AddRow(group, "室温(°C)", record.RoomTemperature.ToString("F1"));
AddRow(group, "浸润时间(h)", record.SoakingTime.ToString("F1"));
AddRow(group, "测试液体", record.Liquid?.Name);
AddRow(group, "液体生产厂家", record.LiquidManufacturer);
AddRow(group, "泡点压力", $"{record.BubblePointPressure} {record.PressureUnit}");
AddRow(group, "最大孔径(μm)", record.MaxPoreSize.ToString("F3"));
table.RowGroups.Add(group);
doc.Blocks.Add(table);
doc.Blocks.Add(new Paragraph(new Run("本报告依据 GB/T 32361-2015 生成。"))
{
FontStyle = FontStyles.Italic,
TextAlignment = TextAlignment.Center,
Margin = new Thickness(0, 20, 0, 0)
});
return doc;
}
private static FlowDocument CreatePoreDistributionDocument(PoreDistributionRecord record)
{
FlowDocument doc = new FlowDocument();
doc.PageWidth = 800;
// 标题
doc.Blocks.Add(new Paragraph(new Run("孔分布测试报告"))
{
FontSize = 24,
FontWeight = FontWeights.Bold,
TextAlignment = TextAlignment.Center
});
doc.Blocks.Add(new Paragraph(new Run($"测试日期: {record.TestDate:yyyy-MM-dd} 测试者: {record.Tester}"))
{
TextAlignment = TextAlignment.Right
});
// 样品信息表格
Table infoTable = new Table();
infoTable.Columns.Add(new TableColumn { Width = new GridLength(150) });
infoTable.Columns.Add(new TableColumn { Width = new GridLength(200) });
TableRowGroup group = new TableRowGroup();
AddRow(group, "膜类型", record.SampleType);
AddRow(group, "规格", record.SampleSpec);
AddRow(group, "室温(°C)", record.RoomTemperature.ToString("F1"));
AddRow(group, "浸润时间(h)", record.SoakingTime.ToString("F1"));
AddRow(group, "测试液体", record.Liquid?.Name);
AddRow(group, "液体生产厂家", record.LiquidManufacturer);
infoTable.RowGroups.Add(group);
doc.Blocks.Add(infoTable);
// 计算结果
doc.Blocks.Add(new Paragraph(new Run("测试结果"))
{
FontSize = 18,
FontWeight = FontWeights.Bold,
Margin = new Thickness(0, 10, 0, 5)
});
Table resultTable = new Table();
resultTable.Columns.Add(new TableColumn { Width = new GridLength(150) });
resultTable.Columns.Add(new TableColumn { Width = new GridLength(200) });
TableRowGroup resultGroup = new TableRowGroup();
AddRow(resultGroup, "泡点压力", $"{record.BubblePointPressure} {record.PressureUnit}");
AddRow(resultGroup, "平均孔径(μm)", record.AveragePoreSize.ToString("F3"));
resultTable.RowGroups.Add(resultGroup);
doc.Blocks.Add(resultTable);
// 数据点列表
doc.Blocks.Add(new Paragraph(new Run("压力-流量数据"))
{
FontSize = 14,
FontWeight = FontWeights.Bold,
Margin = new Thickness(0, 10, 0, 5)
});
Table dataTable = new Table();
dataTable.Columns.Add(new TableColumn { Width = new GridLength(80) });
dataTable.Columns.Add(new TableColumn { Width = new GridLength(80) });
dataTable.Columns.Add(new TableColumn { Width = new GridLength(80) });
dataTable.CellSpacing = 2;
TableRowGroup dataGroup = new TableRowGroup();
// 表头
TableRow headerRow = new TableRow();
headerRow.Cells.Add(new TableCell(new Paragraph(new Run("压力"))));
headerRow.Cells.Add(new TableCell(new Paragraph(new Run("湿膜流量(L/min)"))));
headerRow.Cells.Add(new TableCell(new Paragraph(new Run("干膜流量(L/min)"))));
headerRow.FontWeight = FontWeights.Bold;
dataGroup.Rows.Add(headerRow);
foreach (var dp in record.DataPoints)
{
TableRow row = new TableRow();
row.Cells.Add(new TableCell(new Paragraph(new Run(dp.Pressure.ToString("F2")))));
row.Cells.Add(new TableCell(new Paragraph(new Run(dp.WetFlow.ToString("F3")))));
row.Cells.Add(new TableCell(new Paragraph(new Run(dp.DryFlow.ToString("F3")))));
dataGroup.Rows.Add(row);
}
dataTable.RowGroups.Add(dataGroup);
doc.Blocks.Add(dataTable);
// 孔分布结果
if (record.PoreDistributions != null && record.PoreDistributions.Any())
{
doc.Blocks.Add(new Paragraph(new Run("孔分布"))
{
FontSize = 14,
FontWeight = FontWeights.Bold,
Margin = new Thickness(0, 10, 0, 5)
});
Table distTable = new Table();
distTable.Columns.Add(new TableColumn { Width = new GridLength(80) });
distTable.Columns.Add(new TableColumn { Width = new GridLength(80) });
distTable.Columns.Add(new TableColumn { Width = new GridLength(80) });
TableRowGroup distGroup = new TableRowGroup();
TableRow distHeader = new TableRow();
distHeader.Cells.Add(new TableCell(new Paragraph(new Run("孔径下限(μm)"))));
distHeader.Cells.Add(new TableCell(new Paragraph(new Run("孔径上限(μm)"))));
distHeader.Cells.Add(new TableCell(new Paragraph(new Run("百分比(%)"))));
distHeader.FontWeight = FontWeights.Bold;
distGroup.Rows.Add(distHeader);
foreach (var pd in record.PoreDistributions)
{
TableRow row = new TableRow();
row.Cells.Add(new TableCell(new Paragraph(new Run(pd.LowerPore.ToString("F3")))));
row.Cells.Add(new TableCell(new Paragraph(new Run(pd.UpperPore.ToString("F3")))));
row.Cells.Add(new TableCell(new Paragraph(new Run(pd.Percentage.ToString("F1")))));
distGroup.Rows.Add(row);
}
distTable.RowGroups.Add(distGroup);
doc.Blocks.Add(distTable);
}
doc.Blocks.Add(new Paragraph(new Run("本报告依据 GB/T 32361-2015 生成。"))
{
FontStyle = FontStyles.Italic,
TextAlignment = TextAlignment.Center,
Margin = new Thickness(0, 20, 0, 0)
});
return doc;
}
private static void AddRow(TableRowGroup group, string label, string value)
{
TableRow row = new TableRow();
row.Cells.Add(new TableCell(new Paragraph(new Run(label))));
row.Cells.Add(new TableCell(new Paragraph(new Run(value ?? ""))));
group.Rows.Add(row);
}
private static void ShowPrintPreview(FlowDocument document, string title)
{
PrintDialog printDialog = new PrintDialog();
if (printDialog.ShowDialog() == true)
{
// 调整文档页面大小以匹配打印机
document.PageHeight = printDialog.PrintableAreaHeight;
document.PageWidth = printDialog.PrintableAreaWidth;
document.PagePadding = new Thickness(50);
IDocumentPaginatorSource dps = document;
printDialog.PrintDocument(dps.DocumentPaginator, title);
}
}
}
}