iReport 笔记(三) 使用JavaBean集合作为数据源 【转】

本文介绍如何使用JavaBean作为数据源生成报表,包括定义JavaBean、配置iReport、编程导出PDF等步骤,并提供了完整的示例代码。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

使用JDBC作为报表数据源其实是有很多缺陷的,例如,它要求使用SQL查询作为数据来源,但有时报表的内容并不能由一条SQL语句完成。因此,使用JavaBean集合作为数据源才是终极的解决之道,用户只需要将数据整理到一个JavaBean集合之中就可以了,无论用什么方法,数据源为何物。

3.1 定义Bean
定义一个最简单的Bean,只包含一个属性,如下所示:

package lld.test.ireport;

public class ProductBean
...{
    private String productName;

    public String getProductName()
    ...{
        return productName;
    }

    public void setProductName(String productName)
    ...{
        this.productName = productName;
    }
}
3.2 在iReport中设定数据源及创建报表
要在iReport中使用JavaBean作为数据源,首先要定义好Classpath,以使iReport能够找到我们定义的Bean,使用菜单“Options”-“Classpath”定义Classpath,定义的路径为编译后的.class文件所在路径,例如,我定义的Classpath为“D:/Work/Java/ireport_test/WebContent/WEB-INF/classes”。

在菜单“Data”-“Connections/Datasources”菜单中,添加数据源,将数据源类型设为“JavaBeans set data source”,设定的数据源属性如下图所示:

datasource

按道理而言,上图中的“Factory class”和 “The static method to call to retrieve the array or the collection of javaBeans”中,应该填写相应的工厂类及方法,然后,我们就能够在iReport集成环境中测试输出结果,但就我测试结果而言,发现在我赋上实际的工厂类后,按下Test按钮后,总是提示“The method doen't return a valid array or java.util.Collection”。所以,我们就只把iReport作为一个报表编辑器好了,不要对它报太大奢望,毕竟不花钱,有点bug(或者是我猪头没找对方法)也就原谅一下了。

将其设为当前数据源,然后到菜单“Data”-“Report Query”中定义需要用到的 Bean属性,在“Class name”中输入自定义Bean的名称,本例中为“lld.test.ireport.ProductBean”,然后点击“Read attributes”按钮,获取Bean属性,点击“Add Selected Field(s)”添加要用的属性,如下图所示:

datasource

 

秉承本人所作笔记的一贯风格,只作最主要的功能描述,用最简单的代码描述最核心的功能,因此定义的报表非常之简单,各位如果有兴趣的话,可以加上边框线之类的美化元素,如下图所示:

testReport

该文件名为report_2.jrxml,编译即可获取report_2.jasper

3.3 编程导出PDF
对于Web应用,以PDF格式导出报表是最常见的应用,另外如果是使用C/S模式的话,还可以导出来JRViewer格式。至于其它格式,例如Excel、HTML、Java2D图形等,基本上是自找麻烦,因为导出来的格式很难看,用户会有意见,不如自己去手工生成的好。

对于JavaBean集合,最终仍然要转化成为JRDataSource以供JasperReport使用,不过这个转换很简单,一行代码即足够,示例代码如下所示:

List<?> data = new ArrayList<?>();

...(填充数据)

//生成JRDataSource
JRDataSource dataSource = new JRBeanCollectionDataSource(data);
下面的代码是一个生成PDF的完整示例(Servlet):

package lld.test.ireport;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.j2ee.servlets.BaseHttpServlet;

public class BeanReportServlet extends HttpServlet
...{
    private static final long serialVersionUID = 348226870594216833L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException
    ...{
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException
    ...{
        try
        ...{
            //生成测试数据
            ArrayList<ProductBean> data = new ArrayList<ProductBean>();
            for(int i = 1; i <= 100; i++)
            ...{
                ProductBean bean = new ProductBean();
                bean.setProductName("Product " + i);
                data.add(bean);
            }
            JRDataSource dataSource = new JRBeanCollectionDataSource(data);
           
            //获取报表模板文件
            String root_path = this.getServletContext().getRealPath("/");
            root_path = root_path.replace('/', '/');
            String reportFilePath = root_path + "WEB-INF/classes/lld/test/ireport/report_2.jasper";
            System.out.println("jasper file is " + reportFilePath);
           
            //生成JasperPrint
            JasperReport report = (JasperReport)JRLoader.loadObject(reportFilePath);
            JasperPrint jasperPrint = JasperFillManager.fillReport(report, null, dataSource);

            //设定输出格式
            OutputStream ouputStream = resp.getOutputStream(); 
            resp.setContentType("application/pdf");
            resp.setCharacterEncoding("UTF-8"); 
            resp.setHeader("Content-Disposition", "attachment; filename="" 
                    + URLEncoder.encode("PDF报表", "UTF-8") + ".pdf""); 
                   
            // 使用JRPdfExproter导出器导出pdf 
            JRPdfExporter exporter = new JRPdfExporter(); 
            // 设置JasperPrintList 
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); 
            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream); 
            exporter.exportReport();
           
            ouputStream.close(); 
        } catch (Exception e)
        ...{
            e.printStackTrace();
        }   
    }

}
在上例中,我生成数据源的方式很简单,只是顺序成生了100个ProductBean对象。

JasperReport生成报表时使用的参数传递方式比较奇怪,它不是使用常规的函数参数传递方式,而是需要调用相应Exporter对象的setParameter方法,设定各个参数值,怎一个BT了得,莫非是为了配合它的文档收费计划?

实话实说,上例中的好多代码也是从网上copy来的,在些感谢各位在网上无私奉献的同仁。

3.4 报表生成方式
目前我知道两种报表的生成方式,一种是使用JRPdfExporter对象,上面的例子即是使用的该方法,还有一种方法是使用JasperRunManager对象,示例代码如下所示:

byte[] bytes = JasperRunManager.runReportToPdf(reportFilePath, null, dataSource);
outputStream.write(bytes, 0, bytes.length);
outputStream.close(); 
注:如需本例源码,可留言或通过邮件lldwolf@163.com索取

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lldwolf/archive/2008/05/19/2458278.aspx

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值