我是个 Eclipse RCP 开发新手,IReport + JasperReport
报表开发更是头次接触,客户要求在很短的时间内设计出像样的报表来。这二者结合的问题,让我郁闷了三天三夜,险些缴械;最后在崩溃边缘终于成功搞定。
特别要说明的是,很奇怪 IReport + JasperReport
的绝大部分参考资料,作者都喜欢用 JDBC Connnection
来做示例,也就是说报表的内容完全由 sql
查询语句来构造。像我这样的人对此真是深恶痛绝:在实际应用中 sql
语句的可读性太差,而且报表稍微复杂一些的话,sql
语句根本无能为力。其实对大多数用户来说,JRBeanDataSource
应该是最常用也是最实用的,可惜讲述用 JRBeanDataSource
来做数据源的资料真是少之又少。更要命的是,99%的参考资料都是把Jasperreport放在Web
Application的环境下讲述的,让 RCP
开发的程序员又是郁闷加郁闷。
发完牢骚,接下来,本文将从一个完全的新手角度,讲述一下如何在
Eclipse RCP
开发环境下生成JasperReport报表。目的是让更多的类似我这样的新手不再郁闷,那滋味可真不好受。:(
环境与版本:
OS:Windows XP SP2;
JDK:5.0 update 6;(JDK6 处理 JasperReport 似乎有 bug
,不推荐)
IReport:2.0.1
JasperReport:2.0.1(为与 IReport 使用的 JasperReport
包一致,这个jasperreports-2.0.1.jar可直接从%IReport%\lib目录下拷到
project 中来,并加入project 的 builder path 和 runtime 的
classpath)
Eclipse:3.3.1.1;
WindowBuilder:Professional 6.5.0
首先,打开IReport,把Options->classpath中,把jasperreports-2.0.1.jar加入。否则在接下来配置报表的数据源变量时会出错。
用 New Document
设计一个主表,命名为report,以.jrxml格式保存。
然后在主表中用 subreport 向导,在 detail
区域生成一个subreport,数据源类型选择 JR
Datasource(切记!),文件寻址方式选 SUBREPORT_DIR方式,命名为
subreport1 ,也以 .jrxml 格式保存在 report.jrxml
的同一目录下。
主表和子表都需要通过 fields/variables/parameters
编辑器中指定你在报表中需要的字段。fields是你要显示在报表中的内容;parameters是你要在程序里传给报表的参数名;variables我暂时还没用到。
在主表中把子表的数据源设置为 use data source expression
的方式,使用变量
$P{MyDatasource}
在主表中把变量MyDatasource的值设为net.sf.jasperreports.engine.data.JRBeanCollectionDataSource这个类。
必须强调的是:在稍后的主程序里必须把 SUBREPORT_DIR
这个参数传给主表,否则程序由于没有参考路径而找不到字表,控制台必定报
can't load object from subreport1.jasper
的错!这个问题曾让我郁闷两天而莫名奇妙。
在报表里设计好fields和parameters以后,接下来用一个带 main
函数的类来测试一下:
-
import java.util.*;
-
import java.io.*;
-
import net.sf.jasperreports.engine.*;
-
import net.sf.jasperreports.engine.data.*;
-
import net.sf.jasperreports.view.*;
-
import net.sf.jasperreports.engine.util.JRLoader;
-
import net.sf.jasperreports.engine.JREmptyDataSource;
-
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
-
-
...
-
-
-
public static void main(String[] args) {
-
JasperPrint print = null;
-
try {
-
-
// 由 IReport 做好报表格式后(.jrxml),用该方法编译成 JasperReport 支持的 .jasper 格式:
-
// 这里使用了子报表(subreport),子报表也需要被编译成 jasper 文件
-
-
JasperCompileManager.compileReportToFile("e:/report.jrxml","e:/report.jasper");
-
-
JasperCompileManager.compileReportToFile("e:/subreport1.jrxml","e:/subreport1.jasper");
-
InputStream is = new FileInputStream("e:/report.jasper");
-
JasperReport jasperReport = (JasperReport) JRLoader.loadObject(is);
-
-
-
// HashMap 里存放的 key ,对应着报表中的 $P{key} :
-
-
-
BizEvaluationNodeDao bend = new BizEvaluationNodeDao();
-
List<BizEvaluationNode> temps = bend.getAll();
-
-
List<BizEvaluationNode> result = new ArrayList<BizEvaluationNode>();
-
for (int i = 0; i < temps.size(); i++) {
-
BizEvaluationNode ben = temps.get(i);
-
ben.setSequence(new Integer(i + 1));
-
result.add(ben);
-
}
-
HashMap<String, Object> parameters = new HashMap<String, Object>();
-
parameters.put("SUBREPORT_DIR", "e:/");//使用子报表的话,这个参数必须设置!
-
parameters.put("MyDatasource", new JRBeanCollectionDataSource(result));//把子报表要用的数据源传给父报表,然后父报表再把它传给子报表
-
//result里存放的对象的属性,跟子报表的 field 严格对应,且有 get 和 set 方法。JRBeanCollectionDataSource 将自动通过这些 get 方法访问 result 中对应的 field。
-
print = JasperFillManager.fillReport(jasperReport, parameters,
-
new JRBeanCollectionDataSource(result));
-
-
-
JasperViewer.viewReport(print, false);
-
-
System.out.println("done!");
-
-
} catch (Exception ex) {
-
ex.printStackTrace();
-
}
-
}
然后运行该类,应该可以看到主表和字表效果了。:)
转自:http://blog.sina.com.cn/s/blog_49ebdf2501008jha.html
阅读(2715) | 评论(0) | 转发(0) |