You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用Spring已配置的dataSource创建JRDataSource用于Jasper报表打印?

用Spring配置的DataSource生成JRDataSource的几种方法

嘿,这个问题我太熟悉了!既然你已经在Spring配置类里搞定了DataSource,那把它转换成Jasper报表需要的JRDataSource其实没什么难度,给你分享两种最常用的方案:

方案1:直接用Jasper的JdbcDataSource包装Spring DataSource

这是最省心的方式,Jasper自带的JdbcDataSource可以直接接收标准的JDBC DataSource,完美适配你已经配置好的Spring DataSource。

代码示例

首先在你的服务类里注入Spring的DataSource:

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JdbcDataSource;
import javax.sql.DataSource;
import org.springframework.stereotype.Service;

@Service
public class JasperReportService {

    private final DataSource springDataSource;

    // 推荐用构造注入(Spring 4.3+支持),比@Autowired更稳妥
    public JasperReportService(DataSource springDataSource) {
        this.springDataSource = springDataSource;
    }

    public void generateReport() throws JRException {
        // 1. 把Spring DataSource包装成Jasper的JdbcDataSource
        JdbcDataSource jrDataSource = new JdbcDataSource();
        jrDataSource.setDataSource(springDataSource);

        // 2. 填充报表(这里假设你已经有编译好的.jasper文件路径)
        String reportPath = "classpath:reports/your_report.jasper";
        JasperFillManager.fillReport(reportPath, null, jrDataSource);

        // 后续的报表导出(PDF/Excel等)逻辑就按你自己的需求写啦
    }
}

这种方式的好处是不用自己写SQL查询,报表文件里的SQL会直接通过这个JdbcDataSource执行,非常适合报表逻辑已经定义在.jrxml里的场景。

方案2:先执行SQL拿到ResultSet,再转成JRResultSetDataSource

如果需要在代码里灵活控制查询逻辑(比如动态拼接SQL、传参数),那可以先借助Spring的JdbcTemplate执行查询,拿到ResultSet后再包装成JRResultSetDataSource。

代码示例

import org.springframework.jdbc.core.JdbcTemplate;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRResultSetDataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.stereotype.Service;

@Service
public class JasperReportService {

    private final JdbcTemplate jdbcTemplate;

    public JasperReportService(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void generateDynamicReport() throws JRException, SQLException {
        // 1. 执行自定义SQL查询
        String customSql = "SELECT id, name, email FROM users WHERE department = ?";
        String department = "Engineering";

        // 用JdbcTemplate执行查询,拿到ResultSet(用try-with-resources自动关闭资源)
        try (ResultSet rs = jdbcTemplate.getDataSource().getConnection()
                .prepareStatement(customSql)
                .setString(1, department)
                .executeQuery()) {
            // 2. 把ResultSet转换成JRDataSource
            JRResultSetDataSource jrDataSource = new JRResultSetDataSource(rs);

            // 3. 填充报表
            String reportPath = "classpath:reports/dynamic_report.jasper";
            JasperFillManager.fillReport(reportPath, null, jrDataSource);
        }
    }
}

注意:这里用了try-with-resources语法自动关闭ResultSet和Connection,避免资源泄漏。如果你用的是旧版Java,记得手动在finally块里关闭资源。

额外提醒

  • 确保你的项目里已经引入了jasperreports依赖(Maven/Gradle都可以),版本建议选稳定的最新版。
  • 如果报表需要参数,可以在JasperFillManager.fillReport的第二个参数里传入Map<String, Object>类型的参数映射。
  • 如果你用的是Spring Boot,Spring会自动帮你配置好DataSource和JdbcTemplate,直接注入就行,不用额外写配置类。

内容的提问来源于stack exchange,提问作者pheromix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:07:34