JR 精品文章 - JasperReports 学习小结
AD: jr (at) javaresearch.org


首页 | 动态 | 文章 | FAQ  | 新闻 | 下载 | 代码 | 工作 | 调查 | 术语 | 站点 | 图书 | 论坛 | 帮助 | 全部  

TOP | 交流 | 软件 | 专栏 | 开源 | 译/著 | 源码 | API  | 推荐 | FTP  | 积分 | 统计 | 搜索 | Blog | 我们  
首页 » 研究文集 » 打印与报表 搜索标题相关文章 搜索标题相关文章    评论此文章 发表评论     开始监控此文章 开始监控   加入收藏夹  加入收藏夹
JasperReports 学习小结
variable 原创   更新:2008-03-13 10:56:33  版本: 1.0   

最近学习了JasperReports,小结一下,并附上代码。

(一) 基本概念
如果没有接触过报表,刚开始往往摸不着头脑。做个比喻就简单了:如果说网络应用是把数据送到屏幕上,报表则一般是将数据送到文件。文件有多种格式,如 pdf, xml, html, xls 等等。不同的是,网络应用一般是用 html 来表现数据,而报表则用 xml 来表现。为了打印方便,报表当然也需要对数据进行定位和修饰。

JasperReports 是目前较流行的开源报表框架。它的做法是把报表分成了两部分:一是报表样板(template)的制作;一是对样板的数据填充和输出到指定媒介。本文讨论一下 JasperReports 2.0.4 的情况。

报表样板的制作,可利用 iReport 来完成。最简单的概念是定义一些变量(variable),参数(parameter)及字段(field);还可能要定义分组(group)。字段直接对应于填充数据的名称;变量常用来对报表数据依分组地不同进行求和,求平均值等的计算;而参数则用于填充数据是直接输入到报表。

报表样板是 xml 文件,JasperReports 的样板文件后缀是 "jrxml"。这个编辑好的样板文件经编译后,就变成了 Java 类了,其后缀是 "jasper"。为什么要编译呢?编译后成为 Java 类才能与其他类一起工作来完成报表。这就象是 xml Data Binding,不是吗?

好了,样板编译后,就考虑如何注入数据。JasperReports 提供多种选择。一种是在样板的制作时,就直接定义好 sql 语句,并定一好数据源(Data Source)。这样,填充程序只需提供一个 Connection 即可。例子在后。

但上述配置并不太好,就如同在 jsp 中直接访问数据库一样,不太好。本文觉得较好的方式是将数据封装在 JavaBean 中,并利用 JRBeanCollectionDataSource 来填充数据。例子在后。

这样,报表的源文件大概有样板文件(.jrxml),样板编译文件(.jasper)和数据注入文件(.java)三种。而样板编译文件是中间产物,一般可以缓存起来,不一定每次现编译。

(二)举例

假设数据库中有个表格“student”,其内容如下:
  1. test02=# select * from student;
  2.  sid |   name    | age |       dept
  3. -----+-----------+-----+------------------
  4.    6 | liang     |  69 | cs
  5.    7 | zhen      |  70 | cs
  6.    8 | zhao      |  69 | cs
  7.   10 | zhong     |  79 | cs
  8.   11 | michael   |   7 | cs
  9.   12 | david     |   9 | cs
  10.   13 | ben       |   8 | cs
  11.   14 | roylin    |   7 | cs
  12.   15 | dabin     |   7 | cs
  13.   16 | nathon    |   7 | management
  14.   17 | johnathon |   8 | management
  15.    1 | john      |  30 | computer science
  16.    2 | jason     |   7 | computer science
  17.    3 | tracey    |  31 | computer science
  18.    4 | mary      |  37 | computer science
  19.    5 | yang      |  40 | education
  20. (16 rows)


报表的内容就是对各系学生的平均年龄进行报表,并输出到 pdf,xls 格式的文件。

1:样板文件有两个 “student_report_sql_pie.jrxml”及“student_report_pie.jrxml”。样板文件包含一个大饼图(pie chart -- 呵呵):利用 iReport 很容易设置其属性,插入该图后,点击鼠标右键,选择“Chart Properties”>“Chart Data”>“Details”>“Section Value”。其中“Key Expression”是指根据什么来分饼 -- $F{dept},“Value Expression”就是数值,多是从承担计算结果的变量来 -- $V{avg_age},“Lable Expression”只是饼图标签 -- $F{dept}。第一个样本直接包含了 sql query;第二个样本没有 sql query,但注入程序将报表的标题(title)作为参数(parameter)传入。

2:数据注入程序有两个,如下:
  1. package myreport;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.FileOutputStream;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import net.sf.jasperreports.engine.JRExporterParameter;
  7. import net.sf.jasperreports.engine.JasperCompileManager;
  8. import net.sf.jasperreports.engine.JasperExportManager;
  9. import net.sf.jasperreports.engine.JasperFillManager;
  10. import net.sf.jasperreports.engine.JasperPrint;
  11. import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
  12. import net.sf.jasperreports.engine.export.JRXlsExporter;
  13. import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
  14. public class MyReport {
  15.         
  16.     // test embedding an sql query in template and pass a database connection for it.
  17.     public static void test01() {
  18.         
  19.         System.out.println("----- test01 started: passing connection for embedded sql query in template -----");
  20.         try {
  21.             String template_file     = "src/myreport/template/student_report_sql_pie.jrxml";
  22.             String report_file        = "src/myreport/jasper/student_report_sql_pie.jasper";
  23.             String dest_file        = "src/myreport/exp/student_report_sql_pie.pdf";
  24.             
  25.             // 1. compile template to JasperReport        
  26.             JasperCompileManager.compileReportToFile(template_file, report_file);
  27.             System.out.println(">>> template compiled to report file: " + report_file);
  28.             
  29.             // 2. fill the report with data
  30.             JasperPrint print = JasperFillManager.fillReport(report_file, null, StudentReportDAO.getConnection());
  31.             System.out.println(">>> report filled: " + print.toString());
  32.             
  33.             // 3. output filled report to file
  34.             JasperExportManager.exportReportToPdfFile(print, dest_file);
  35.             System.out.println(">>> pdf file exported: " + dest_file);
  36.         }
  37.         catch(Exception e) {
  38.             e.printStackTrace();
  39.         }
  40.     }
  41.     
  42.     // test using a data source to fill report.
  43.     private static void test02() {
  44.         
  45.         System.out.println("----- test02 started: no sql query embedded in report template -----");
  46.         
  47.         try {
  48.             // this set of report has no pie chart and aggregation functions
  49. //            String template_file         = "src/myreport/template/student_report.jrxml";
  50. //            String report_file            = "src/myreport/jasper/student_report.jasper";
  51. //            String dest_file_pdf        = "src/myreport/exp/student_report.pdf";
  52. //            String dest_file_xls        = "src/myreport/exp/student_report.xls";
  53.             
  54.             // this set of report has pie chart
  55.             String template_file     = "src/myreport/template/student_report_pie.jrxml";
  56.             String report_file        = "src/myreport/jasper/student_report_pie.jasper";
  57.             String dest_file_pdf    = "src/myreport/exp/student_report_pie.pdf";
  58.             String dest_file_xls    = "src/myreport/exp/student_report_pie.xls";
  59.             
  60.             // 1. compile template to report object
  61.             JasperCompileManager.compileReportToFile(template_file, report_file);
  62.             System.out.println(">>> template compiled to report file: " + report_file);
  63.             
  64.             // 2. fill the report with data to create print object
  65.             List studentlist = new StudentReportDAO().getStudentList();
  66.             JRBeanCollectionDataSource datasource = new JRBeanCollectionDataSource(studentlist);
  67.             
  68.             // pass the report title as a parameter "myTitle"
  69.             HashMap params = new HashMap();
  70.             params.put("myTitle""My Student Average Age Report");
  71.             
  72.             JasperPrint print = JasperFillManager.fillReport(report_file, params, datasource);
  73.             System.out.println(">>> report filled: " + print.toString());
  74.             
  75.             // 3. output filled report to file
  76.             JasperExportManager.exportReportToPdfFile(print, dest_file_pdf);
  77.             System.out.println(">>> pdf file exported: " + dest_file_pdf);
  78.             
  79.             // 4. ouput filled resprt to excel file
  80.             exportExcel(print, dest_file_xls);
  81.         }
  82.         catch(Exception e) {
  83.             e.printStackTrace();
  84.         }
  85.     }
  86.     
  87.     public static void exportExcel(JasperPrint print, String filename) throws Exception {
  88.         JRXlsExporter exp = new JRXlsExporter(); // excel exporter
  89.         ByteArrayOutputStream out = new ByteArrayOutputStream();
  90.       
  91.         try {
  92.             exp.setParameter(JRExporterParameter.JASPER_PRINT, print);
  93.             exp.setParameter(JRExporterParameter.OUTPUT_STREAM, out);
  94.             exp.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
  95.             exp.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
  96.             exp.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
  97.             exp.exportReport();    // start exporting to the output stream.
  98.    
  99.             new FileOutputStream(filename).write(out.toByteArray());
  100.             
  101.             System.out.println(">>> xls file exported: " + filename);
  102.          } 
  103.          catch (Exception e) {
  104.            throw e;
  105.          }
  106.     }
  107.     
  108.     public static void main(String[] a) {        
  109.         test01();
  110.         test02();
  111.     }
  112. }
  113. package myreport;
  114. import java.sql.Connection;
  115. import java.sql.PreparedStatement;
  116. import java.sql.ResultSet;
  117. import java.sql.SQLException;
  118. import java.util.ArrayList;
  119. import java.util.List;
  120. import org.postgresql.jdbc3.Jdbc3PoolingDataSource;
  121. public class StudentReportDAO {
  122.     
  123.     private static final Jdbc3PoolingDataSource ds = new Jdbc3PoolingDataSource();
  124.     
  125.     private static String select = "select * from student order by dept";
  126.         
  127.     static {
  128.         ds.setDataSourceName("JwangDataSource");
  129.         ds.setServerName("localhost");
  130.         ds.setDatabaseName("test02");
  131.         ds.setUser("john");
  132.         ds.setPassword("password");
  133.         ds.setMaxConnections(10);
  134.     }
  135.     
  136.     public static Connection getConnection() throws SQLException {        
  137.         return ds.getConnection();
  138.     }
  139.     
  140.     public List getStudentList() throws Exception {
  141.         
  142.         Connection conn = null;
  143.         PreparedStatement ps = null;
  144.         ResultSet rs = null;
  145.         
  146.         try {
  147.             conn = getConnection();
  148.             ps = conn.prepareStatement(select);
  149.             rs = ps.executeQuery();
  150.             
  151.             ArrayList list = new ArrayList();
  152.             while(rs.next()) {
  153.                 list.add(create(rs));
  154.             }
  155.             
  156.             return list;
  157.         }
  158.         catch(Exception e) {
  159.             e.printStackTrace();
  160.         }
  161.         finally {
  162.             rs.close();
  163.             ps.close();
  164.             conn.close();
  165.         }
  166.         
  167.         return null;
  168.     }
  169.     
  170.     private MutableStudent create(ResultSet rs) throws SQLException {
  171.         return new MutableStudent(  rs.getInt("sid"),
  172.                                     rs.getString("name"),
  173.                                     rs.getString("dept"),
  174.                                     rs.getInt("age")
  175.                                     );
  176.     }
  177. }
  178. package myreport;
  179. import java.io.Serializable;
  180. /**
  181.  * Value object for table "student"
  182.  */
  183. public class MutableStudent implements Serializable {
  184.     // Note: Data fields must match the "fields" defined in report template.
  185.     private int sid;
  186.     private String name;
  187.     private String dept;
  188.     private int age;
  189.     
  190.     public MutableStudent() {}
  191.     
  192.     public MutableStudent(int sid, String name, String dept, int age) {
  193.         this.sid = sid;
  194.         this.name = name;
  195.         this.dept = dept;
  196.         this.age = age;
  197.     }
  198.     
  199.     public int getSid() {
  200.         return this.sid;
  201.     }
  202.     
  203.     public int getAge() {
  204.         return this.age;
  205.     }
  206.     
  207.     public String getName() {
  208.         return this.name;
  209.     }
  210.     
  211.     public String getDept() {
  212.         return this.dept;
  213.     }
  214. }


注:上传了样本文件:“student_report_pie.jrxml” and pdf output.
附件:student_report_pie.jrxml(15K) 附件:student_report_pie.pdf(20K) 

版权声明   给作者写信
本篇文章对您是否有帮助?  投票:         投票结果:     18       0
作者其它文章: 作者全部文章
评论人:liaoshaobo_2008 发表时间: Thu Mar 13 16:41:01 CST 2008
哈哈,不错多多支持
评论人:liguangxi168 发表时间: Thu Mar 13 16:57:37 CST 2008
[good]
评论人:liguangxi168 发表时间: Thu Mar 13 17:03:52 CST 2008
[good][:E][:)][sun]
评论人:younghappy 发表时间: Thu Mar 13 21:50:29 CST 2008
kljdk
评论人:richilee 发表时间: Fri Mar 14 03:51:58 CST 2008
i do not understand. 
评论人:clmwy 发表时间: Fri Mar 14 15:18:38 CST 2008
顶顶顶
评论人:pengpeng2395 发表时间: Wed Mar 26 15:15:16 CST 2008
fen bu gou???
评论人:pengpeng2395 发表时间: Wed Mar 26 15:21:37 CST 2008
我想看看源码
评论人:xndx 发表时间: Sat Mar 29 16:31:56 CST 2008
学习一下[:)]
评论人:jfkang 发表时间: Thu Apr 03 22:22:38 CST 2008
[:E]正在用ireport做pie,可惜我下载不了
评论人:laonongfu 发表时间: Mon Apr 14 20:28:16 CST 2008
[:E][:(]
评论人:laonongfu 发表时间: Mon Apr 14 20:39:39 CST 2008
不错,以后项目会用到的,学了。
评论人:herolin 发表时间: Tue May 27 22:42:13 CST 2008
大大真不? !![:E]

这个文章共有 13 条评论
主题: 使用JXL读取Excel表格,拷贝、更新Excel工作薄 上一篇文章
返回文章列表 返回〔打印与报表〕
下一篇文章 主题: 如何选择适合自己的WEB报表工具?


文字广告链接
        自主、快速定制基于JAVA的B/S业务系统          重量级企业在线自定义WEB报表平台
        Excel制表、零代码发布、打印、图表结合——快逸报表,免费、稳定、功能强大的java工具
        技术圈: 关于Java、dotNet、PHP、Ruby、奇客、Web2.0等更多资讯博客精选文章

关于 JR  |  版权声明  |  联系我们 

©2002-2006 JR 版权所有 沪ICP备05019622号