1. 简介

在本文中,我们将学习如何将 BIRT(Business Intelligence and Reporting Tools)集成到 Spring Boot MVC 项目中,实现 HTML 与 PDF 格式的静态与动态报表输出。

2. 什么是 BIRT?

BIRT 是一个开源的报表引擎,专为 Java Web 应用设计,支持数据可视化功能。

它是 Eclipse 基金会下的顶级项目,由 IBM 和 Innovent Solutions 共同推动开发,最初由 Actuate 于 2004 年末发起。

该框架支持连接多种数据源,能够灵活地生成各类报表,包括图表、表格等。

3. Maven 依赖配置

BIRT 包含两个核心组件:

✅ 一个是用于创建报表设计文件的可视化报表设计器
✅ 一个是用于解析和渲染报表的运行时组件

我们将在 Spring Boot 项目中同时使用这两个组件。

3.1. 引入 BIRT 框架依赖

官方在 Maven Central 上提供的最新版本是 2016 年的 4.6 版本,但目前 Eclipse 官网已提供更新的 4.8 版本。
虽然可以手动下载并导入依赖库(约 68MB),但更推荐使用由 Innovent Solutions 提供的 Maven 托管版本

<dependency>
    <groupId>com.innoventsolutions.birt.runtime</groupId>
    <artifactId>org.eclipse.birt.runtime_4.8.0-20180626</artifactId>
    <version>4.8.0</version>
</dependency>

3.2. Spring Boot 相关依赖

⚠️ 注意:BIRT 的 JAR 包中自带了 Slf4J 实现,与 Spring Boot 默认使用的 Logback 冲突,因此需要排除 Logback:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
    <exclusions>
        <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </exclusion>
    </exclusions>
</dependency>

至此,项目环境准备完成。

4. BIRT 报表结构

在 BIRT 中,报表是一个 XML 格式的配置文件,后缀为 .rptdesign,用于定义报表的布局、样式、数据源等信息。

生成一个基础动态报表需要配置以下三个部分:

  1. 数据源(如 CSV 文件或数据库)
  2. 显示元素(如表格、图表)
  3. 页面设计(布局、样式)

BIRT 提供了丰富的内置组件,支持主流数据源、图表、表格等,也可以通过扩展机制自定义组件。

5. Eclipse 报表设计器

为了简化报表设计,Eclipse 提供了图形化插件,支持拖拽操作、组件属性编辑、数据源配置等功能。

设计器界面包括:

  • Palette:提供可拖拽的组件
  • Property Editor:选中组件后显示其详细配置
  • Outline:以树形结构展示整个页面结构
  • Data Explorer:管理报表数据源和数据集

如下图所示,展示了设计器界面及数据源配置区域:

birt1

设计器中创建的报表文件路径为:<project_root>/reports/csv_data_report.rptdesign

对于已经使用 Eclipse 的开发者,只需安装 BIRT 插件即可。
未使用 Eclipse 的开发者,可下载 Eclipse Report Designer 工具包,内含预装插件的便携版 Eclipse。

6. 编程方式创建报表

除了图形化设计器,也可以通过代码创建报表,但这种方式文档较少,需要深入源码和社区讨论。

例如,以下代码用于创建一个包含图片和文本的静态报表:

DesignElementHandle element = factory.newSimpleMasterPage("Page Master");
design.getMasterPages().add(element);

GridHandle grid = factory.newGridItem(null, 2, 1);
design.getBody().add(grid);

grid.setWidth("100%"); 

RowHandle row0 = (RowHandle) grid.getRows().get(0);

ImageHandle image = factory.newImage(null);
CellHandle cell = (CellHandle) row0.getCells().get(0);
cell.getContent().add(image);
image.setURL("\"https://www.baeldung.com/wp-content/themes/baeldung/favicon/favicon-96x96.png\"");

LabelHandle label = factory.newLabel(null);
cell = (CellHandle) row0.getCells().get(1);
cell.getContent().add(label);
label.setText("Hello, Baeldung world!");

生成的报表如下图所示:

birt2

报表文件路径为:<project_root>/reports/static_report.rptdesign

7. 配置数据源

BIRT 支持多种数据源类型,包括 CSV、数据库、JDBC 等。

7.1. 配置 CSV 数据源

示例中使用的 CSV 文件内容如下:

Student, Math, Geography, History
Bill, 10,3,8
Tom, 5,6,5
Anne, 7, 4,9

配置步骤如下:

  1. 打开设计器 → 右键点击 Data Sources
  2. 选择 Flat File Data Source
  3. 选择文件路径并设置首行为列名
  4. 测试连接

7.2. 配置数据集

数据源配置完成后,需创建数据集来定义具体显示哪些数据:

  1. 右键点击 Data Sets
  2. 选择对应的数据源
  3. 选择要显示的列
  4. 设置输出列的数据类型
  5. 点击 Preview Results 预览数据

7.3. 其他数据源类型

对于 JDBC 数据源,可能需要编写 SQL 查询语句或调用存储过程。
此外,BIRT 还支持将多个数据集合并为一个新数据集。

8. 报表渲染

报表设计完成后,需通过 BIRT 引擎进行渲染,输出 HTML 或 PDF 等格式。

8.1. 初始化引擎

BIRT 的 ReportEngine 类负责解析报表设计并生成最终输出。
⚠️ 注意:创建引擎实例开销较大,应只创建一次并复用:

@PostConstruct
protected void initialize() throws BirtException {
    EngineConfig config = new EngineConfig();
    config.getAppContext().put("spring", this.context);
    Platform.startup(config);
    IReportEngineFactory factory = (IReportEngineFactory) Platform
      .createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
    birtEngine = factory.createReportEngine(config);
    imageFolder = System.getProperty("user.dir") + File.separatorChar + reportsPath + imagesPath;
    loadReports();
}

@Override
public void destroy() {
    birtEngine.destroy();
    Platform.shutdown();
}

8.2. 输出格式配置

BIRT 支持 HTML、PDF、PPT、ODT 等多种格式。以下为 HTML 和 PDF 的渲染示例:

PDF 渲染

private void generatePDFReport(IReportRunnable report, HttpServletResponse response, 
  HttpServletRequest request) {
    IRunAndRenderTask runAndRenderTask = birtEngine.createRunAndRenderTask(report);
    response.setContentType(birtEngine.getMIMEType("pdf"));
    IRenderOption options = new RenderOption();
    PDFRenderOption pdfRenderOption = new PDFRenderOption(options);
    pdfRenderOption.setOutputFormat("pdf");
    runAndRenderTask.setRenderOption(pdfRenderOption);
    runAndRenderTask.getAppContext().put(EngineConstants.APPCONTEXT_PDF_RENDER_CONTEXT, request);

    try {
        pdfRenderOption.setOutputStream(response.getOutputStream());
        runAndRenderTask.run();
    } catch (Exception e) {
        throw new RuntimeException(e.getMessage(), e);
    } finally {
        runAndRenderTask.close();
    }
}

HTML 渲染

private void generateHTMLReport(IReportRunnable report, HttpServletResponse response, 
  HttpServletRequest request) {
    IRunAndRenderTask runAndRenderTask = birtEngine.createRunAndRenderTask(report);
    response.setContentType(birtEngine.getMIMEType("html"));
    IRenderOption options = new RenderOption();
    HTMLRenderOption htmlOptions = new HTMLRenderOption(options);
    htmlOptions.setOutputFormat("html");
    htmlOptions.setBaseImageURL("/" + reportsPath + imagesPath);
    htmlOptions.setImageDirectory(imageFolder);
    htmlOptions.setImageHandler(htmlImageHandler);
    runAndRenderTask.setRenderOption(htmlOptions);
    runAndRenderTask.getAppContext().put(
      EngineConstants.APPCONTEXT_BIRT_VIEWER_HTTPSERVET_REQUEST, request);

    try {
        htmlOptions.setOutputStream(response.getOutputStream());
        runAndRenderTask.run();
    } catch (Exception e) {
        throw new RuntimeException(e.getMessage(), e);
    } finally {
        runAndRenderTask.close();
    }
}

⚠️ 注意:HTML 渲染需设置图片路径与处理器,推荐使用 HTMLServerImageHandler,避免因路径问题导致图片无法加载。

8.3. 图片资源发布

HTML 报表中图片为外部资源,需确保其在服务器路径下可访问。
我们在 Spring Boot 中配置资源处理器:

@SpringBootApplication
@EnableWebMvc
public class ReportEngineApplication implements WebMvcConfigurer {
    @Value("${reports.relative.path}")
    private String reportsPath;
    @Value("${images.relative.path}")
    private String imagesPath;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry
          .addResourceHandler(reportsPath + imagesPath + "/**")
          .addResourceLocations("file:///" + System.getProperty("user.dir") + "/" 
            + reportsPath + imagesPath);
    }
}

9. 控制器配置

最后,我们编写一个控制器用于接收请求并返回报表结果:

@RequestMapping(method = RequestMethod.GET, value = "/report/{name}")
@ResponseBody
public void generateFullReport(HttpServletResponse response, HttpServletRequest request,
  @PathVariable("name") String name, @RequestParam("output") String output) 
  throws EngineException, IOException {
    OutputType format = OutputType.from(output);
    reportService.generateMainReport(name, format, response, request);
}

用户可通过 URL 参数 output 指定输出格式,如:

  • /report/csv_data_report?output=pdf
  • /report/csv_data_report?output=html
  • /report/static_report?output=pdf
  • /report/static_report?output=html

报表效果如下图所示:

birt4

刷新报表只需访问:/report/reload

10. 小结

本文演示了如何将 BIRT 集成到 Spring Boot 应用中,涵盖了依赖配置、报表设计、数据源配置、渲染逻辑及图片处理等关键步骤。

虽然 BIRT 学习曲线较陡,但其灵活性和功能强大,非常适合作为企业级报表解决方案。

完整源码可访问:GitHub 项目地址


原始标题:BIRT Reporting with Spring Boot