更新excel 数据 C值更新
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user