更新excel 数据 C值更新

This commit is contained in:
GukSang.Jin
2026-06-01 16:48:38 +08:00
parent b891a5b8a0
commit f5f4dc73ac
5 changed files with 83 additions and 10 deletions

View File

@@ -18,7 +18,7 @@ public sealed class ModbusRealtimeDataService : IRealtimeDataService
private const ushort OrificeTemperatureRegister = 30;
private const ushort SampleTemperatureRegister = 36;
private const ushort AbsorbanceRegister = 120;
private const ushort CFactorRegister = 312;
private const ushort CFactorRegister = 308;
private const ushort HeatReleaseRateRegister = 354;
private const ushort PeakHeatReleaseRateRegister = 376;
private const ushort Qa180Register = 366;

View File

@@ -153,6 +153,9 @@ public sealed class NpoiReportExportService : IReportExportService
{
ClearSheet(sheet);
var fourDecimalCellStyle = sheet.Workbook.CreateCellStyle();
fourDecimalCellStyle.DataFormat = sheet.Workbook.CreateDataFormat().GetFormat("0.0000");
var headerRow = sheet.CreateRow(0);
for (var i = 0; i < DataHeaders.Length; i++)
{
@@ -191,7 +194,7 @@ public sealed class NpoiReportExportService : IReportExportService
SetNumeric(row, 22, record.CurrentMass);
SetNumeric(row, 23, record.InitialMass);
SetNumeric(row, 24, record.PeakHeatReleaseRate);
SetNumeric(row, 25, record.CFactor);
SetNumeric(row, 25, record.CFactor, fourDecimalCellStyle);
}
for (var i = 0; i < DataHeaders.Length; i++)
@@ -524,11 +527,16 @@ public sealed class NpoiReportExportService : IReportExportService
}
}
private static void SetNumeric(IRow row, int columnIndex, double value)
private static void SetNumeric(IRow row, int columnIndex, double value, ICellStyle? cellStyle = null)
{
if (double.IsFinite(value))
{
row.CreateCell(columnIndex).SetCellValue(value);
var cell = row.CreateCell(columnIndex);
cell.SetCellValue(value);
if (cellStyle is not null)
{
cell.CellStyle = cellStyle;
}
}
}
@@ -601,7 +609,9 @@ public sealed class NpoiReportExportService : IReportExportService
private static string FormatValue(double? value)
{
return value is null || !double.IsFinite(value.Value) ? "" : $"{value.Value:0.00}";
return value is null || !double.IsFinite(value.Value)
? ""
: value.Value.ToString("0.0000", CultureInfo.InvariantCulture);
}
private static string FormatSeconds(int? value)

View File

@@ -25,7 +25,10 @@ public sealed class MainViewModel : ObservableObject
_deviceStatusText = tcpDeviceConnectionService.StatusText;
_tcpDeviceConnectionService.ConnectionStatusChanged += DeviceConnectionStatusChanged;
var testPage = new TestPageViewModel(experimentDataService, tcpDeviceConnectionService);
var reportPage = new ReportPageViewModel(experimentDataService, reportExportService);
var reportPage = new ReportPageViewModel(
experimentDataService,
reportExportService,
tcpDeviceConnectionService);
NavigationItems = [];
var testItem = new NavigationItemViewModel("测试界面", testPage);

View File

@@ -31,14 +31,14 @@ public sealed class ReportFieldViewModel : ObservableObject
}
}
public void SetAutoValue(string value)
public void SetAutoValue(string value, bool overwriteManual = false)
{
if (string.IsNullOrWhiteSpace(value))
{
return;
}
if (!string.IsNullOrWhiteSpace(Value) && !_isAutoFilled)
if (!overwriteManual && !string.IsNullOrWhiteSpace(Value) && !_isAutoFilled)
{
return;
}

View File

@@ -14,16 +14,26 @@ namespace ConeCalorimeter.ViewModels;
public sealed class ReportPageViewModel : PageViewModel
{
private const ushort CFactorRegister = 308;
private const double CFactorMinimum = 0;
private const double CFactorMaximum = 1000;
private const double DisplayZeroTolerance = 0.00005;
private const string FourDecimalDisplayFormat = "0.0000";
private readonly IExperimentDataService _experimentDataService;
private readonly IReportExportService _reportExportService;
private readonly ITcpDeviceConnectionService _tcpDeviceConnectionService;
private ModbusFloatByteOrder? _cFactorByteOrder;
private string _statusText = "报表信息可手动录入,导出时会合并当前采集数据。";
public ReportPageViewModel(
IExperimentDataService experimentDataService,
IReportExportService reportExportService) : base("报表")
IReportExportService reportExportService,
ITcpDeviceConnectionService tcpDeviceConnectionService) : base("报表")
{
_experimentDataService = experimentDataService;
_reportExportService = reportExportService;
_tcpDeviceConnectionService = tcpDeviceConnectionService;
Sections = CreateSections();
SummaryItems =
@@ -160,6 +170,7 @@ public sealed class ReportPageViewModel : PageViewModel
return;
}
RefreshCurrentCValueReportField(overwriteManual: true);
var input = BuildInput();
var defaultName = BuildDefaultFileName(input);
var dialog = new SaveFileDialog
@@ -255,6 +266,48 @@ public sealed class ReportPageViewModel : PageViewModel
FindField("EndTime")?.SetAutoValue(FormatSeconds(LastNonNegative(records, record => record.TestSeconds)));
}
private void RefreshCurrentCValueReportField(bool overwriteManual)
{
if (TryReadCurrentCValueText(out var value))
{
FindField("CFactor")?.SetAutoValue(value, overwriteManual);
}
}
private bool TryReadCurrentCValueText(out string value)
{
value = string.Empty;
if (!_tcpDeviceConnectionService.TryReadFloatValues(CFactorRegister, out var result))
{
Log.Warning(
"Report C factor D{RegisterAddress} read failed before export. ConnectionStatus={ConnectionStatus}.",
CFactorRegister,
_tcpDeviceConnectionService.StatusText);
return false;
}
if (!ModbusFloatSelector.TrySelectRangedFloat(
result,
CFactorMinimum,
CFactorMaximum,
out var byteOrder,
out var cFactor,
out var matchCount,
_cFactorByteOrder))
{
Log.Warning(
"Report C factor D{RegisterAddress} has no valid decoded value. Raw={RawHex}, Matches={MatchCount}.",
CFactorRegister,
result.RawHex,
matchCount);
return false;
}
_cFactorByteOrder = byteOrder;
value = FormatValue(NormalizeDisplayValue(cFactor));
return true;
}
private ReportFieldViewModel? FindField(string key)
{
return Sections.SelectMany(section => section.Fields)
@@ -296,7 +349,14 @@ public sealed class ReportPageViewModel : PageViewModel
private static string FormatValue(double value)
{
return double.IsFinite(value) ? $"{value:0.00}" : string.Empty;
return double.IsFinite(value)
? value.ToString(FourDecimalDisplayFormat, CultureInfo.InvariantCulture)
: string.Empty;
}
private static double NormalizeDisplayValue(double value)
{
return Math.Abs(value) < DisplayZeroTolerance ? 0 : value;
}
private static bool IsValidExperimentRecord(RealtimeDataRecord record)