213 lines
7.2 KiB
Markdown
213 lines
7.2 KiB
Markdown
# XP.ReportEngine — PDF 报告生成引擎
|
||
|
||
## 概述
|
||
|
||
XP.ReportEngine 是 XplorePlane 平面 CT 检测系统的 PDF 报告生成模块。负责将 XP.ImageProcessing 的检测分析结果(距离测量、BGA 气泡率、空隙测量、通孔填锡率)转换为结构化的 PDF 检测报告。
|
||
|
||
模块采用管线式架构(Pipeline),将报告生成过程分解为五个独立阶段:
|
||
**模板加载 → 数据适配 → 数据绑定 → 排版计算 → PDF 渲染**
|
||
|
||
## 技术栈
|
||
|
||
| 依赖 | 版本 | 用途 |
|
||
|------|------|------|
|
||
| .NET 8.0 | net8.0-windows7.0 | 运行时 |
|
||
| itext7 | 8.0.5 | PDF 文档生成核心库 |
|
||
| itext7.bouncy-castle-adapter | 8.0.5 | iText 7 加密支持 |
|
||
| Newtonsoft.Json | 13.0.3 | JSON 模板反序列化 |
|
||
| Prism.Wpf | 9.0.537 | 模块化框架与 DI |
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
XP.ReportEngine/
|
||
├── Interfaces/ # 核心接口定义
|
||
│ ├── IReportGenerator.cs
|
||
│ ├── IReportGeneratorFactory.cs
|
||
│ ├── ITemplateEngine.cs
|
||
│ ├── IDataBinder.cs
|
||
│ ├── ILayoutEngine.cs
|
||
│ ├── IPdfRenderer.cs
|
||
│ └── IReportDataAdapter.cs
|
||
├── Models/ # 数据模型
|
||
│ ├── ReportContext.cs
|
||
│ ├── ImageData.cs
|
||
│ ├── ReportTemplate.cs
|
||
│ ├── TemplateElement.cs
|
||
│ ├── LayoutPage.cs
|
||
│ ├── ReportResult.cs
|
||
│ ├── ReportGenerationOptions.cs
|
||
│ └── ProcessorOutput.cs
|
||
├── Services/ # 服务实现
|
||
│ ├── PdfReportGenerator.cs # 管线协调器
|
||
│ ├── ReportGeneratorFactory.cs # 工厂
|
||
│ ├── JsonTemplateEngine.cs # JSON 模板加载与验证
|
||
│ ├── ExpressionDataBinder.cs # ${} 表达式数据绑定
|
||
│ ├── PageLayoutEngine.cs # 分页与排版
|
||
│ ├── ITextPdfRenderer.cs # iText 7 PDF 渲染
|
||
│ ├── ProcessorDataAdapter.cs # 处理器数据适配
|
||
│ └── ReportIdGenerator.cs # 报告编号生成
|
||
├── Fonts/ # 字体目录(当前使用系统字体,目录保留备用)
|
||
├── Templates/ # JSON 报告模板
|
||
│ └── StandardReportTemplate.json
|
||
├── Resources/ # 多语言资源文件
|
||
│ ├── Resources.resx
|
||
│ ├── Resources.zh-CN.resx
|
||
│ ├── Resources.zh-TW.resx
|
||
│ └── Resources.en-US.resx
|
||
├── Documents/ # 项目文档
|
||
├── ReportEngineModule.cs # Prism 模块入口
|
||
└── XP.ReportEngine.csproj
|
||
```
|
||
|
||
## 快速开始
|
||
|
||
### 1. 字体说明
|
||
|
||
模块使用 Windows 系统自带字体(微软雅黑 + Arial),无需额外添加字体文件。详见 `Documents/FontFilesGuidance.md`。
|
||
|
||
### 2. 通过 DI 容器调用
|
||
|
||
模块通过 `ReportEngineModule` 自动注册到 Prism DI 容器,其他模块可直接注入 `IReportGenerator` 使用:
|
||
|
||
```csharp
|
||
public class MyService
|
||
{
|
||
private readonly IReportGenerator _reportGenerator;
|
||
|
||
public MyService(IReportGenerator reportGenerator)
|
||
{
|
||
_reportGenerator = reportGenerator;
|
||
}
|
||
|
||
public async Task GenerateReport()
|
||
{
|
||
var context = new ReportContext
|
||
{
|
||
Metadata = new ReportMetadata
|
||
{
|
||
ReportId = "RPT-20250511-001",
|
||
InspectionDate = DateTime.Now,
|
||
SampleName = "PCB-001",
|
||
OperatorName = "张三"
|
||
},
|
||
Properties = new Dictionary<string, object>
|
||
{
|
||
["sampleName"] = "PCB-001"
|
||
}
|
||
};
|
||
|
||
var options = new ReportGenerationOptions
|
||
{
|
||
TemplatePath = "Templates/StandardReportTemplate.json",
|
||
OutputFilePath = @"D:\Reports\report.pdf",
|
||
Format = ReportOutputFormat.Pdf
|
||
};
|
||
|
||
var result = await _reportGenerator.GenerateAsync(context, options);
|
||
|
||
if (result.IsSuccess)
|
||
{
|
||
// PDF 已保存到 OutputFilePath
|
||
}
|
||
else
|
||
{
|
||
// result.ErrorMessage 包含错误信息
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. 使用数据适配器
|
||
|
||
将 XP.ImageProcessing 处理器输出转换为 ReportContext:
|
||
|
||
```csharp
|
||
var adapter = container.Resolve<IReportDataAdapter>();
|
||
|
||
var processorOutputs = new List<ProcessorOutput>
|
||
{
|
||
new ProcessorOutput
|
||
{
|
||
ProcessorType = "BgaVoidRateProcessor",
|
||
OutputData = new Dictionary<string, object>
|
||
{
|
||
["BgaCount"] = 120,
|
||
["VoidRate"] = 0.035,
|
||
["Classification"] = "Pass"
|
||
}
|
||
}
|
||
};
|
||
|
||
var metadata = new ReportMetadata
|
||
{
|
||
ReportId = "RPT-20250511-001",
|
||
InspectionDate = DateTime.Now,
|
||
SampleName = "PCB-001",
|
||
OperatorName = "张三"
|
||
};
|
||
|
||
ReportContext context = adapter.Adapt(processorOutputs, metadata);
|
||
```
|
||
|
||
## 核心接口
|
||
|
||
| 接口 | 实现类 | 职责 |
|
||
|------|--------|------|
|
||
| `IReportGenerator` | `PdfReportGenerator` | 协调管线各阶段,生成 PDF |
|
||
| `IReportGeneratorFactory` | `ReportGeneratorFactory` | 根据格式创建对应生成器 |
|
||
| `ITemplateEngine` | `JsonTemplateEngine` | JSON 模板加载、反序列化、验证 |
|
||
| `IDataBinder` | `ExpressionDataBinder` | `${}` 表达式解析与数据绑定 |
|
||
| `ILayoutEngine` | `PageLayoutEngine` | 分页、元素定位、表格跨页 |
|
||
| `IPdfRenderer` | `ITextPdfRenderer` | 使用 iText 7 渲染 PDF |
|
||
| `IReportDataAdapter` | `ProcessorDataAdapter` | OutputData → ReportContext 转换 |
|
||
|
||
## 数据绑定表达式
|
||
|
||
模板中支持以下绑定语法:
|
||
|
||
| 语法 | 说明 | 示例 |
|
||
|------|------|------|
|
||
| `${propertyName}` | 简单属性绑定 | `${sampleName}` |
|
||
| `${object.property}` | 嵌套属性路径 | `${metadata.reportId}` |
|
||
| `${list[index]}` | 列表索引访问 | `${bgaBalls[0].voidRate}` |
|
||
| `${functionName(param)}` | 格式化函数 | `${formatDate(inspectionDate)}` |
|
||
| `${loc:ResourceKey}` | 本地化键解析 | `${loc:Report_Title}` |
|
||
|
||
内置格式化函数:
|
||
- `formatDate(value)` — 根据当前语言格式化日期
|
||
- `formatNumber(value, decimals)` — 根据当前语言格式化数字
|
||
- `formatPercent(value)` — 格式化百分比
|
||
|
||
## 多语言支持
|
||
|
||
支持三种语言:简体中文(zh-CN)、繁体中文(zh-TW)、英文(en-US)。
|
||
|
||
通过 `ILocalizationService` 自动解析 `${loc:Key}` 表达式为当前语言文本。模块在初始化时注册资源源到 Fallback Chain。
|
||
|
||
## 模板定义
|
||
|
||
标准模板位于 `Templates/StandardReportTemplate.json`,包含以下页面类型:
|
||
- `homepage` — 报告首页(元数据 + 摘要表格)
|
||
- `metricData` — 距离测量数据页
|
||
- `bgaInspection` — BGA 焊球检测页(含数据表格)
|
||
- `voidInspection` — 空隙检测页(含数据表格)
|
||
- `viaFillInspection` — 通孔填锡检测页
|
||
|
||
模板 JSON 结构需包含三个必需顶层字段:`document`、`pages`、`styles`。
|
||
|
||
## 错误处理
|
||
|
||
模块采用结果对象模式(Result Pattern),所有公共方法返回 `ReportResult` 而非抛出异常:
|
||
- `ReportResult.Success(stream)` — 成功,包含 PDF MemoryStream
|
||
- `ReportResult.Failure(message, ex)` — 失败,包含错误信息和可选异常
|
||
|
||
非致命性问题(缺失属性、未定义样式、图像缺失)会记录警告日志并继续执行,不会中断报告生成。
|
||
|
||
## 构建
|
||
|
||
```bash
|
||
cd XplorePlane
|
||
dotnet build XP.ReportEngine/XP.ReportEngine.csproj
|
||
```
|