返回首页

JasperReports 的模块化库 jasper-modular

jasper-modular 库通过类型化 Java 类和注解简化 JasperReports 中子报表的工作。自动 JRXML 和参数生成消除了手动数据钻取。支持复杂报表的嵌套和集合。

jasper-modular:JasperReports 中无痛的模块化报表
Advertisement 728x90

JasperReports模块化库:简化子报表与数据处理

在JasperReports中处理大型报表时,常导致JRXML文件变得臃肿不堪。设计、数据逻辑和业务规则混杂在一起,使得维护工作困难重重。子报表虽能解决模块化问题,但向其中传递数据却带来了复杂性。

常见的数据处理方式:

  • 单一JSON:使用JsonDataSource并在XML中指定路径。路径错误在编译时无法捕获,且REPORT_DATA_SOURCE是隐式传递的。
  • 模板中的SQL:通过REPORT_CONNECTION执行查询。逻辑位于Java代码之外,缺乏类型检查。
  • 传递REPORT_DATA_SOURCE:可消费的数据源在第一个子报表后即被耗尽。
  • 手动参数:需要数十个<subreportParameter>标签和Java中的params.put()调用,必须保持同步。

jasper-modular库的核心原理

该库向每个子报表传递两个参数:

Google AdInline article slot
  • <prefix>Report — 已编译的JasperReport对象。
  • <prefix>MapParameter — 包含数据的Map<String, Object>。

映射通过REPORT_PARAMETERS_MAP解包:键名直接成为$P{key},无需<subreportParameter>标签。注解处理器在编译期间生成参数和JRXML文件。渲染器利用反射递归填充子报表。

添加依赖项

适用于JasperReports 7.x:

<dependency>
    <groupId>io.github.hhdevr</groupId>
    <artifactId>jasper-modular-starter-jr7</artifactId>
    <version>1.0.0</version>
</dependency>

适用于6.x:

Google AdInline article slot
<dependency>
    <groupId>io.github.hhdevr</groupId>
    <artifactId>jasper-modular-starter-jr6</artifactId>
    <version>1.0.0</version>
</dependency>

在maven-compiler-plugin中配置注解处理器:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <annotationProcessorPaths>
            <path>
                <groupId>io.github.hhdevr</groupId>
                <artifactId>jasper-modular-processor-jr7</artifactId>
                <version>1.0.0</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

报表类结构

根报表:

@Getter
@Setter
@JasperModularReport(templatePath = "/reports/company_report.jrxml")
public class CompanyReport extends ModularReport {
    private TitleSubModule titleSubModule;
    private FinancialSubModule financialSubModule;
}

子报表:

Google AdInline article slot
@Getter
@Setter
@JasperSubreport(templatePath = "/reports/sub_title_report.jrxml", prefix = "Title")
public class TitleSubModule extends SubreportModule {
    private CompanyDetails companyDetails;
    private String period;
    private String currency;

    @Override
    public boolean isEmpty() {
        return companyDetails == null;
    }
}

嵌套结构:FinancialSubModule包含RevenueSubModule、ExpenseSubModule和ProfitSubModule。每个模块通过isEmpty()检查实现条件渲染。

集合处理:

@JasperCollection(columnWidth = 150)
private List<RevenueItem> items;

排除字段:

@JasperIgnore
private transient String internalCache;

JRXML生成模式

注解处理器在target/generated-sources/目录下更新模板:

  • CREATE:生成完整的JRXML,包含参数、数据集、集合组件和子报表区域。
  • INJECT(默认):添加缺失元素,同时保留现有设计。
  • NONE:不做任何更改。

生成后,可在Jaspersoft Studio中进一步优化模板。

示例项目结构:

  • CompanyReport

- TitleSubModule(CompanyDetails、period、currency)

- FinancialSubModule

- RevenueSubModule(totalRevenue、growthPercent、List<RevenueItem>)

- ExpenseSubModule(totalExpenses、growthPercent、List<ExpenseItem>)

- ProfitSubModule(grossProfit、operatingProfit、netProfit、margin、List<ProfitBreakdown>)

核心要点

  • 通过Java类实现模块化:子报表作为字段,数据具有类型安全。
  • 注解处理器自动生成参数和JRXML文件。
  • 无需手动传递数据,实现递归渲染。
  • 支持@JasperCollection处理集合,嵌套深度无限制。
  • 兼容JasperReports 6.x/7.x和Spring Boot 3.x/4.x。

— Editorial Team

Advertisement 728x90

继续阅读