5.5 KiB
5.5 KiB
报表打印系统架构与使用说明
本文档详细介绍了当前报表打印系统的架构设计、核心组件及其使用方法。
1. 架构设计概览
本系统采用 Provider 模式 与 流式任务构建 (Builder Pattern) 相结合的设计,旨在实现报表生成的解耦、灵活配置与高扩展性。
核心组件
-
IReportDataProvider (报表数据提供者)
- 职责:定义单一报表的元数据(模版、标题、类型)和数据准备逻辑。
- 优势:将业务逻辑从 Service 层剥离,每个报表对应一个 Provider,互不干扰,易于维护。
- 关键方法:
getReportType(): 唯一标识(如APPLICATION_FORM)。prepareData(params): 准备模版所需的数据。getCoverProviderType(): 定义关联的封面类型(支持自动封面)。
-
ReportPrintJob (打印任务构建器)
- 职责:负责组装打印任务。它像一条流水线,可以按需添加封面、报表片段、设置公章/水印等。
- 特性:
- 链式调用:
createJob().addCover().addBatch().render()。 - 混合布局:自动处理横向 (Landscape) 与纵向 (Portrait) 页面的合并。
- 上下文注入:支持注入 CompanyId 用于公章/水印生成。
- 链式调用:
-
ReportRenderService (渲染服务)
- 职责:底层的渲染引擎。
- 功能:
- 解析 Velocity 模版。
- 调用 Gotenberg 进行 HTML 转 PDF。
- 处理水印 (Watermark) 和电子公章 (Seal)。
- 合并多个 PDF 片段。
2. 现有报表类型
目前系统已实现的 Provider 如下:
| 报表类型 (Type) | Provider 类 | 描述 |
|---|---|---|
APPLICATION_FORM |
DriverApplicationFormProvider |
驾驶员应聘申请表 |
ID_CARD_SCAN |
IdCardScanProvider |
身份证扫描件 |
DRIVER_LICENSE_COPY |
DriverLicenseCopyProvider |
驾驶证复印件 |
QUALIFICATION_CERTIFICATE_COPY |
QualificationCertificateCopyProvider |
从业资格证复印件 |
QUALIFICATION_REVIEW |
QualificationReviewProvider |
资格审查及技能考核登记表 |
ACCIDENT_RECORD |
AccidentRecordProvider |
安全行车事故记录 (横向) |
VIOLATION_RECORD |
ViolationRecordProvider |
违章记录 (横向) |
ANNUAL_ASSESSMENT_RECORD |
AnnualAssessmentRecordProvider |
年度考核记录 |
MEDICAL_EXAMINATION_REPORT |
MedicalExaminationReportProvider |
体检报告 |
REWARD_PUNISHMENT_RECORD |
RewardPunishmentRecordProvider |
奖惩记录表 |
3. 使用方法 (开发指南)
3.1 创建新报表
-
定义 Provider: 新建一个类实现
IReportDataProvider,并注册为 Spring Bean (@Component)。@Component public class MyReportProvider implements IReportDataProvider { @Override public String getReportType() { return "MY_REPORT"; } @Override public String getTemplateCode() { return "templates/my/report.html.vm"; } @Override public Map<String, Object> prepareData(Map<String, Object> params) { // 准备数据... return Map.of("data", "value"); } } -
创建 Velocity 模版: 在
src/main/resources/templates/my/report.html.vm中编写 HTML。
3.2 调用打印服务
在业务 Service 中注入 ReportRenderService 和 providerMap,然后使用链式调用:
场景 A:单个报表打印 (带自动封面)
public byte[] printMyReport(List<String> ids) {
// 1. 获取 Provider
IReportDataProvider provider = providerMap.get("MY_REPORT");
// 2. 构建任务
return reportRenderService.createJob(providerMap::get) // 传入查找器以支持自动封面
.withCompanyId(companyId) // 设置公司ID(用于公章)
.addCover(provider) // 自动添加关联封面
.addBatch(provider, ids, "id") // 批量添加报表内容
.useSeal(true) // 启用公章
.render(); // 渲染并返回 PDF
}
场景 B:一键打印 (多报表合并)
public byte[] printAll(List<String> driverIds, List<String> types) {
var job = reportRenderService.createJob(providerMap::get)
.withCompanyId(companyId)
.useSeal(false); // 全局公章开关
for (String id : driverIds) {
// 1. 为每个驾驶员添加一个独立封面
job.addCover("COMMON_COVER", Map.of(
"title", "驾驶员档案",
"subtitle", "张三"
));
// 2. 依次添加选中的报表
for (String type : types) {
job.add(providerMap.get(type), Map.of("driverId", id));
}
}
return job.render();
}
3.3 进阶配置
- 横向布局:在 Provider 中重写
isLandscape()返回true,或者在 Job 中调用.isLandscape(true)(通常由 Provider 决定)。 - 自定义封面:Provider 可重写
getCoverProviderType()指定特定封面,或重写getCoverData()自定义封面参数。 - 水印控制:
job.useWatermark(true).watermarkText("自定义水印")。
4. 模版工具支持
模版中内置了 $tool 工具类 (ReportVelocityTool),提供常用功能:
$tool.getDictLabel('type', value): 字典翻译$tool.formatDate(date, 'yyyy-MM-dd'): 日期格式化$tool.getOssUrls(urlStr): 解析 OSS 图片链接$tool.numberToChinese(num): 数字转中文大写
文档生成日期:2026-03-01