## Compilation fixes - Fix XAML namespace reference XplorePlane.Converters → XplorePlane.Helpers (EventLogView, StateDisplayView) - Add missing using for ISampleTypeRepository / JsonSampleTypeRepository in App.xaml.cs - Fix ILoggerService.Warn() calls using Exception as first arg instead of message string - Serialize CncProgram to JSON when passing to MatrixLayout (expects string, not CncProgram object) - Suppress CS8632 nullable annotation warnings project-wide ## BGA wizard fixes - Fix preview not showing on step 3: force RefreshBgaPreview() when entering final step - Add step validation in CanNext() to prevent skipping to preview with invalid inputs - Notify NextCommand.CanExecuteChanged when inputs change - Fix RunProgress runtime binding error: set Mode=OneWay for ProgressBar.Value ## Operator toolbox: prevent duplicate insertion - Add static OperatorTarget property for direct dispatch to active pipeline - PipelineEditorView registers as toolbox target on load (floating window only) - CNC page sets initial target; PipelineEditorWindow resets to CNC pipeline on close - '+' button inserts only to the active pipeline instead of broadcasting to all subscribers ## Pipeline editor status bar messages - Add StatusBarMessageEvent / StatusBarMessagePayload to CommonEvents.cs - PipelineEditorViewModel publishes status on all ops (add/remove/reorder/save/execute) - MainViewModel subscribes and displays on main window bottom status bar - Auto-clear after timeout (3s info, 5s error) ## docs - Merge three architecture docs into consolidated XplorePlane-架构与结构说明.md
XP.ReportEngine — 多格式报告生成引擎
概述
XP.ReportEngine 是 XplorePlane 平面 CT 检测系统的报告生成模块。负责将检测分析结果(距离测量、BGA 气泡率、空隙测量、通孔填锡率)转换为结构化的检测报告。
支持 四种输出格式:
- PDF(默认)— 正式归档报告,管线式架构(模板加载 → 数据绑定 → 排版 → PDF 渲染)
- TXT — 纯文本,面向人工快速阅读
- CSV — 逗号分隔值,面向数据二次处理(Excel / 数据分析工具)
- Excel (.xlsx) — 富格式工作簿,分组工作表 + 嵌入图像,支持模板填充
对外提供 IReportService 门面接口,外部模块只需构建 ReportRequest(可指定 1~4 种格式)即可一行调用完成报告生成。
技术栈
| 依赖 | 版本 | 用途 |
|---|---|---|
| .NET 8.0 | net8.0-windows7.0 | 运行时 |
| iText7 | 8.0.5 | PDF 文档生成核心库 |
| itext7.bouncy-castle-adapter | 8.0.5 | iText7 加密支持 |
| ClosedXML | 0.104.x | Excel (.xlsx) 工作簿读写与图像嵌入 |
| System.Text.Encoding.CodePages | — | .NET 8 中启用 GB2312/GBK 代码页编码 |
| Newtonsoft.Json | 13.0.3 | JSON 模板反序列化 |
| Prism.Wpf | 9.0.537 | 模块化框架与 DI |
| Telerik UI for WPF | 2024.1.408 | UI 控件(演示窗口) |
| XP.Common | — | 日志、本地化、通用窗体、PDF 阅读器 |
项目结构
XP.ReportEngine/
├── Configs/ # 配置加载
│ ├── ConfigLoader.cs
│ └── ReportConfig.cs
├── Interfaces/ # 核心接口定义
│ ├── IReportService.cs ★ 门面接口(外部调用入口)
│ ├── IReportGenerator.cs
│ ├── IReportGeneratorFactory.cs
│ ├── ITemplateEngine.cs
│ ├── IDataBinder.cs
│ ├── ILayoutEngine.cs
│ ├── IPdfRenderer.cs
│ └── IReportDataAdapter.cs
├── Models/ # 数据模型
│ ├── ReportRequest.cs ★ 报告生成请求
│ ├── ReportServiceResult.cs ★ 报告服务结果
│ ├── ReportContext.cs
│ ├── ReportMetadata.cs
│ ├── ImageData.cs
│ ├── ReportSection.cs ★ 分段重复(repeat section)数据
│ ├── ReportTemplate.cs
│ ├── TemplateElement.cs
│ ├── LayoutPage.cs
│ ├── ReportResult.cs
│ ├── ReportGenerationOptions.cs
│ ├── ProcessorOutput.cs
│ └── TemplateValidationResult.cs
├── Services/ # 服务实现
│ ├── ReportService.cs ★ 门面服务实现(多格式编排)
│ ├── PdfReportGenerator.cs # PDF 管线协调器
│ ├── TxtReportGenerator.cs # TXT 纯文本生成器
│ ├── CsvReportGenerator.cs # CSV 生成器(RFC 4180)
│ ├── ExcelReportGenerator.cs # Excel 生成器(ClosedXML)
│ ├── TextReportGeneratorBase.cs # TXT/CSV 共享基类
│ ├── ExcelSheetNameSanitizer.cs # 工作表名规整
│ ├── ReportFormatExtensions.cs # 格式→扩展名映射
│ ├── EncodingResolver.cs # 编码解析(UTF-8/GB2312/GBK)
│ ├── PlaceholderRef.cs # 模板占位符索引数据结构
│ ├── ReportGeneratorFactory.cs # 工厂(PDF/TXT/CSV/Excel)
│ ├── JsonTemplateEngine.cs # JSON 模板加载与验证
│ ├── ExpressionDataBinder.cs # ${} 表达式数据绑定
│ ├── PageLayoutEngine.cs # 分页与排版
│ ├── ITextPdfRenderer.cs # iText7 PDF 渲染
│ ├── ProcessorDataAdapter.cs # 处理器数据适配
│ └── ReportIdGenerator.cs # 报告编号生成(RPT-yyyyMMdd-NNN)
├── Templates/ # JSON 报告模板
│ └── StandardReportTemplate.json
│ └── CncInspectionReportTemplate.json # CNC 检测报告(首页 + 逐节点详情 repeat 页)
├── Resources/ # 多语言资源文件
│ ├── Resources.resx
│ ├── Resources.zh-CN.resx
│ ├── Resources.zh-TW.resx
│ └── Resources.en-US.resx
├── ViewModels/ # 演示窗口 ViewModel
│ └── ReportDemoViewModel.cs
├── Views/ # 演示窗口 View
│ ├── ReportDemoWindow.xaml
│ └── ReportDemoWindow.xaml.cs
├── Documents/ # 项目文档
│ ├── README.md ← 本文件
│ ├── Guidance.md # 使用指南(PDF)
│ ├── MultiFormatOutputGuide.md # 多格式输出指南(TXT/CSV/Excel)
│ ├── App.config.example # 配置示例(含多格式配置项)
│ ├── FontFilesGuidance.md # 字体方案说明
│ ├── TemplateDevelopment.md # PDF 模板开发指南
│ ├── XP.ReportEngineDesign.md # 架构设计文档
│ └── XP.ReportEngineModelDefine.md # 模型定义文档
├── ReportEngineModule.cs # Prism 模块入口
└── XP.ReportEngine.csproj
核心接口
| 接口 | 实现类 | 职责 |
|---|---|---|
IReportService |
ReportService |
门面接口,多格式编排入口 + 图像转PDF |
IReportGenerator |
PdfReportGenerator |
PDF 管线协调 |
IReportGenerator |
TxtReportGenerator |
TXT 纯文本生成 |
IReportGenerator |
CsvReportGenerator |
CSV(RFC 4180)生成 |
IReportGenerator |
ExcelReportGenerator |
Excel (.xlsx) 生成(ClosedXML) |
IReportGeneratorFactory |
ReportGeneratorFactory |
根据格式创建对应生成器 |
ITemplateEngine |
JsonTemplateEngine |
JSON 模板加载、反序列化、验证 |
IDataBinder |
ExpressionDataBinder |
${} 表达式解析与数据绑定 |
ILayoutEngine |
PageLayoutEngine |
分页、元素定位、表格跨页 |
IPdfRenderer |
ITextPdfRenderer |
使用 iText7 渲染 PDF |
IReportDataAdapter |
ProcessorDataAdapter |
ProcessorOutput → ReportContext 转换 |
架构分层
┌─────────────────────────────────────────────────────┐
│ 外部调用方(XP.App、其他模块) │
│ 注入 IReportService,传入 ReportRequest │
│ (可指定 Formats = [Pdf, Txt, Csv, Excel]) │
└──────────────────────┬──────────────────────────────┘
│
┌──────────────────────▼──────────────────────────────┐
│ ReportService(门面层 + 多格式编排) │
│ 格式校验 → 报告ID → 数据适配(一次) → 多格式循环 │
└──────────────────────┬──────────────────────────────┘
│ foreach format
┌──────────────────────▼──────────────────────────────┐
│ ReportGeneratorFactory → 按格式创建生成器 │
│ Pdf → PdfReportGenerator(管线:模板→绑定→排版→渲染)│
│ Txt → TxtReportGenerator(纯文本,等宽列对齐) │
│ Csv → CsvReportGenerator(RFC 4180,并集表头) │
│ Excel → ExcelReportGenerator(ClosedXML,模板/结构化)│
└─────────────────────────────────────────────────────┘
快速开始
详细使用指南请参阅 Documents/Guidance.md。
图像转 PDF(快捷打印/保存)
// 方式 1:传入图像文件路径
var result = await _reportService.GenerateImagePdfAsync(@"D:\Images\sample.png");
// 方式 2:传入 WPF BitmapSource
var result = await _reportService.GenerateImagePdfAsync(bitmapSource);
// 方式 3:传入 ImageData 对象
var result = await _reportService.GenerateImagePdfAsync(new ImageData
{
SourceType = ImageSourceType.Bytes,
Bytes = imageBytes
});
// 生成后自动打开系统默认 PDF 阅读器,用户可在阅读器中保存或打印
// PDF 保存到 Report:OutputDirectory 配置目录下的 ImagePdf 子文件夹
// 例如:D:\XPData\Report\ImagePdf\Image_20250707_143025.pdf
最简调用(通过 IReportService)
public class MyService
{
private readonly IReportService _reportService;
public MyService(IReportService reportService)
{
_reportService = reportService;
}
public async Task GenerateReport(List<ProcessorOutput> outputs)
{
var request = new ReportRequest
{
ProcessorOutputs = outputs,
Metadata = new ReportMetadata
{
SampleName = "PCB-001",
OperatorName = "张三",
InspectionDate = DateTime.Now
},
// 指定输出格式(可选,默认 PDF)| Specify output formats (optional, defaults to PDF)
// 支持同时生成多种格式(最多 4 种不重复)| Supports generating multiple formats simultaneously (up to 4 distinct)
Formats = new List<ReportOutputFormat>
{
ReportOutputFormat.Pdf,
ReportOutputFormat.Excel
}
};
var result = await _reportService.GenerateAsync(request);
if (result.IsSuccess)
{
// result.OutputFilePath — 首个格式的输出路径(向后兼容)
// result.OutputFilePaths — 各格式路径列表
foreach (var output in result.OutputFilePaths)
{
Console.WriteLine($"{output.Format}: {output.FilePath}");
}
}
}
}
预热机制
模块在 Prism 初始化时自动在后台执行一次预热(WarmUpAsync),触发 iText7 初始化、字体加载、JIT 编译等一次性开销,避免用户首次生成报告时卡顿。
预热与正式生成通过 SemaphoreSlim 互斥锁串行执行,不会出现并发冲突。
数据绑定表达式
模板中支持以下绑定语法:
| 语法 | 说明 | 示例 |
|---|---|---|
${propertyName} |
简单属性绑定 | ${sampleName} |
${object.property} |
嵌套属性路径 | ${metadata.reportId} |
${list[index]} |
列表索引访问 | ${bgaBalls[0].voidRate} |
${functionName(param)} |
格式化函数 | ${formatDate(inspectionDate)} |
${loc:ResourceKey} |
本地化键解析 | ${loc:Report_Title} |
模板分段重复(repeat section)
模板页可声明 "repeat": "<键名>",引擎在数据绑定阶段按 ReportContext.Properties 中该键对应的分段列表(IEnumerable<ReportSection>)将本页克隆渲染多次,每份在「全局叠加分段(分段优先)」的作用域内解析 ${}、图像与表格 dataKey。适用于「按列表逐项各占一页」的场景(如 CNC 检测的多个检测节点)。详见 Documents/TemplateDevelopment.md 第 11 节。
此外,ReportRequest.TemplatePathOverride 支持在单次请求中指定 PDF 模板(相对路径基于应用基目录解析,仅对 PDF 生效),用于「同一套引擎、不同业务用不同模板」。内置模板 Templates/CncInspectionReportTemplate.json 即为 CNC 检测报告(首页 + 逐节点详情重复页)。
多语言支持
支持三种语言:简体中文(zh-CN)、繁体中文(zh-TW)、英文(en-US)。
通过 ILocalizationService 自动解析 ${loc:Key} 表达式为当前语言文本。模块在初始化时注册资源源到 Fallback Chain。
模板页面类型
标准模板 StandardReportTemplate.json 包含以下页面类型:
| 页面类型 | 说明 |
|---|---|
homepage |
报告首页(公司信息 + 元数据 + 汇总表格) |
summary |
检测结果汇总页 |
metricData |
距离测量数据页 |
bgaInspection |
BGA 焊球检测页(含数据表格) |
voidInspection |
空隙检测页(含数据表格) |
viaFillInspection |
通孔填锡检测页 |
CNC 检测报告模板 CncInspectionReportTemplate.json 包含 homepage(运行信息 + 总览图 + 节点汇总表)与 nodeDetail(repeat: "nodeSections" 的逐节点详情页)。
错误处理
模块采用结果对象模式(Result Pattern):
ReportServiceResult.Success(path, reportId)— 成功ReportServiceResult.Failure(message, ex)— 失败
非致命性问题(缺失属性、图像缺失)会记录警告日志并继续执行,不会中断报告生成。
构建
cd XplorePlane
dotnet build XP.ReportEngine/XP.ReportEngine.csproj
相关文档
Documents/Guidance.md— 详细使用指南(IReportService 调用方式)Documents/MultiFormatOutputGuide.md— 多格式输出指南(TXT/CSV/Excel 用法与配置)Documents/TemplateDevelopment.md— PDF 模板开发指南(新增/自定义模板)Documents/App.config.example— 配置文件示例(含多格式配置项)Documents/FontFilesGuidance.md— 字体方案说明Documents/XP.ReportEngineDesign.md— 架构设计文档Documents/XP.ReportEngineModelDefine.md— 模型定义文档