Files
wucaixing-backend/REPORT_SYSTEM_GUIDE.md
2026-05-13 16:14:53 +08:00

5.5 KiB
Raw Permalink Blame History

报表打印系统架构与使用说明

本文档详细介绍了当前报表打印系统的架构设计、核心组件及其使用方法。

1. 架构设计概览

本系统采用 Provider 模式流式任务构建 (Builder Pattern) 相结合的设计,旨在实现报表生成的解耦、灵活配置与高扩展性。

核心组件

  1. IReportDataProvider (报表数据提供者)

    • 职责:定义单一报表的元数据(模版、标题、类型)和数据准备逻辑。
    • 优势:将业务逻辑从 Service 层剥离,每个报表对应一个 Provider互不干扰易于维护。
    • 关键方法
      • getReportType(): 唯一标识(如 APPLICATION_FORM)。
      • prepareData(params): 准备模版所需的数据。
      • getCoverProviderType(): 定义关联的封面类型(支持自动封面)。
  2. ReportPrintJob (打印任务构建器)

    • 职责:负责组装打印任务。它像一条流水线,可以按需添加封面、报表片段、设置公章/水印等。
    • 特性
      • 链式调用createJob().addCover().addBatch().render()
      • 混合布局:自动处理横向 (Landscape) 与纵向 (Portrait) 页面的合并。
      • 上下文注入:支持注入 CompanyId 用于公章/水印生成。
  3. 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 创建新报表

  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");
        }
    }
    
  2. 创建 Velocity 模版src/main/resources/templates/my/report.html.vm 中编写 HTML。

3.2 调用打印服务

在业务 Service 中注入 ReportRenderServiceproviderMap,然后使用链式调用:

场景 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