JasperReport报表设计总结(一)

共三篇,下接:http://jimmy-shine.javaeye.com/blog/123595

为了开发报表,已经拜读了一大堆的资料,其中大部分是重复的。可以看得出,国人还是比较热衷于copy&paste的工作。所以找了一大堆的资料都是相同的,或者可以用一个词来形容,换汤不换药的。
有必要对于jasper Report的学习进度进行一下总结,一来可以更新一下以前的资料中的一些旧得不能再旧的不再适用的东西,二来让后来者可以轻松的上手。
首先,jasperReport是一个以java实现的报表工具,(好像是句废话)。可以实现多种格式的报表。
再我们先理解一下jasperReport的实现过程。笔者不再画图,网上到处都是。
1)定制报表格式。
  有二种方式,一种就是写jrxml文件,其实就是xml文件,只不过是后缀名不一样罢了。另一种方式更直接,就是生成一个JasperDesign类的实 例,在japsperDesign中自己定义模板。jrxml文件也是通过一个JRXmlLoad加载过来,转成JasperDesign类的实例。也就 是说写jrxml文件还需要进行解析,加载。现实中我们使用的报表一般格式比较固定,因而可以通过先使用iReport工具生成模板,再加载解析的方式。 这种方式简单,而且可见性强。
2)填充数据。
  在最新版(2007.4.30发布)的jasperReports1.3.3中,支持了很多的格式,包括了对于Hibernate的支持。填充数据对于我 们经常使用的来说,一般是二种方式,一种方式是通过JDBC连接提供数据源,一种就是通过javaBean的集合提供数据源。当然还有web Service的xml文件提供的。我的建议是,如果你的程序中的统计直接使用Jdbc就可以完成,那么就使用jdbc数据源的方法,反之,使用 javaBean的集合是不错的选择,因为这样不会在意你的数据的来源,你也可以任意处理,比如说,要通过权限检查的数据才在报表中生成的话,就可以过滤 到不符合权限的数据。
3)显示或打印。
  显示,即将JasperReport生成的文件直接显示出来,打印所使用的方式其实就是生成文件,然后调用打印来对文件进行打印。
看起来是不是很简单,对,确实很简单。
笔者主要从事基于B/S模式的开发,相信大部分人的使用也是基于web进行使用。故笔者对于基于web的开发进行详细讲述。

1、工程环境配置。
将以下包加入WEB-INF/lib中。
commons-beanutils-1.7.jar;commons-collections-2.1.jar;commons-digester-1.7.jar;commons-logging-1.0.2.jar;commons-logging-api-1.0.2.jar;itext-1.3.1.jar;jasperreports-1.3.3.jar;jdt-compiler-3.1.1.jar;jxl-2.6.jar;png-encoder-1.5.jar;poi-2.0-final-20040126.jar
   以上包是jasperReport必须。
2、iReport的安装
   这个很简单,直接下一步就可以了。
3、使用iReport生成 .jasper文件
.jasper是经过编译的japserReport模板,即.jrxml编译后的。
对于iReport的使用网络上已经有了详细的中文的文档,具体可以下载附件查看。使用.jasper文件可以避免在系统中再进行编译,增加系统的压力。
4、数据填充
数据填充是相对于比较重要的一步,数据填充的目的是为了将数据填充进去,生成一个JapserPrint对象。笔者在之前已经阐述过,现在主要是基于关系 型数据库(比较简单的,没有权限控制的),以及基于JavaBean Collection进行数据填充。进行数据填充的基本就是一定要实现JRDataSource,JRDataSource定义了二个方法,一个是指针移 动的方法next(),另一个是取值的getFieldValue()方法,用来取值填充。
对于关系型数据库,即直接利用数据库的表来生成报表的,只需要传入一个Java Connection即可。JasperReport已经有了个默认的实现的JRDataSource的接口了。对于Java Conncetion的获得,笔者建议使用工厂方法或者使用Spring方式来获得。可以参照笔者写的如下:

java 代码
 
    • /**  
    •  * @copyRight Beijing Tsing-Tech Reachway Software Co.,Ltd.  
    •  * @author Jimmy.Shine 2007-5-11  
    •  */   
    • package  cn.com.reachway.framework.report;   
    •   
    • import  java.sql.Connection;   
    • import  java.sql.DriverManager;   
    •   
    • import  cn.com.reachway.framework.exception.JasperReportException;   
    •   
    • /**  
    •  * Used for get a JDBC connection for Jasper Report  
    •  */   
    • public   class  JDBCConnection {   
    •   /**  
    •   * Which Jdbc driver were used. Like: "net.sourceforge.jtds.jdbc.Driver"  
    •   */   
    •   private  String jdbcDriver;   
    •   /**  
    •   * The jdbc url,define which database server,which db. Like:  
    •   * "jdbc:jtds:sqlserver://192.168.1.50:1433;DatabaseName=JAVA5;SelectMethod=Cursor"  
    •   */   
    •   private  String jdbcUrl;   
    •   
    •   private  String dbUser;   
    •   
    •   private  String dbPassword;   
    •   
    •   public  String getDbPassword() {   
    •    return  dbPassword;   
    •  }   
    •   
    •   public   void  setDbPassword(String dbPassword) {   
    •    this .dbPassword = dbPassword;   
    •  }   
    •   
    •   public  String getDbUser() {   
    •    return  dbUser;   
    •  }   
    •   
    •   public   void  setDbUser(String dbUser) {   
    •    this .dbUser = dbUser;   
    •  }   
    •   
    •   public  String getJdbcDriver() {   
    •    return  jdbcDriver;   
    •  }   
    •   
    •   public   void  setJdbcDriver(String jdbcDriver) {   
    •    this .jdbcDriver = jdbcDriver;   
    •  }   
    •   
    •   public  String getJdbcUrl() {   
    •    return  jdbcUrl;   
    •  }   
    •   
    •   public   void  setJdbcUrl(String jdbcUrl) {   
    •    this .jdbcUrl = jdbcUrl;   
    •  }   
    •   
    •   public  JDBCConnection() {   
    •    super ();   
    •  }   
    •   /**  
    •   * Get the Connection   
    •   * @return connection  
    •   * @throws JasperReportException  
    •   */   
    •   public  Connection getConnection()  throws  JasperReportException {   
    •   Connection con;   
    •    try  {   
    •    check();   
    •    Class.forName( this .jdbcDriver);   
    •    con = DriverManager.getConnection( this .jdbcUrl,  this .dbUser,  this .dbPassword);   
    •     return  con;   
    •   }  catch  (Exception e) {   
    •    e.printStackTrace();   
    •     throw   new  JasperReportException( "Get JDBC Connection Error" );   
    •   }   
    •  }   
    •     
    •   /**  
    •   * Check the Configure  
    •   * @throws JasperReportException  
    •   */   
    •   private   void  check()  throws  JasperReportException {   
    •    if  ( this .jdbcDriver ==  null  ||  this .jdbcDriver.equals( "" ) ||  this .jdbcUrl ==  null  ||  this .jdbcUrl.equals( "" )   
    •     ||  this .dbUser ==  null  ||  this .dbUser.equals( "" ) ||  this .dbPassword ==  null ) {   
    •     throw   new  JasperReportException( "Jdbc Configure error!" );   
    •   }   
    •  }   
    •   
    • }   
    •   


java 代码
 
    • /**  
    •  * @copyRight Beijing Tsing-Tech Reachway Software Co.,Ltd.  
    •  * @author Jimmy.Shine 2007-5-14  
    •  */   
    • package  cn.com.reachway.framework.report.dataSource;   
    •   
    • import  net.sf.jasperreports.engine.JRDataSource;   
    • import  net.sf.jasperreports.engine.JRException;   
    • import  net.sf.jasperreports.engine.JRField;   
    •   
    • /**  
    •  * 报表的dataSource的基类,所有利用DataSource产生报表的继承此类  
    •  */   
    • public   abstract   class  ReportDataSource  implements  JRDataSource {   
    •   
    •   /**  
    •   * 取值  
    •   */   
    •   public   abstract  Object getFieldValue(JRField jrField)  throws  JRException;   
    •   
    •   /**  
    •   * 指针移动  
    •   */   
    •   public   abstract   boolean  next()  throws  JRException;   
    •   
    • }   
    •   

  这样可以共用配置文件中的jdbc连接的相关参数。
对于其它的数据源,JavaBean Collection,笔者采用了一个抽象类,使用抽象类的目的,是为了使开发者尽可能不用直接接触jasperReport(此为笔者自己的方式,笔者 是PM,为了考虑底下的人的开发)。以下为抽象类以及笔者提供的一个sample:

 
    • /**  
    •  * @copyRight Beijing Tsing-Tech Reachway Software Co.,Ltd.  
    •  * @author Jimmy.Shine 2007-5-14  
    •  */   
    • package  cn.com.reachway.framework.report.dataSource;   
    •   
    • import  java.util.ArrayList;   
    • import  java.util.List;   
    •   
    • import  net.sf.jasperreports.engine.JRException;   
    • import  net.sf.jasperreports.engine.JRField;   
    •   
    • /**  
    •  * 利用JavaBean Collection生成ReportDataSource的例子  
    •  */   
    • public   class  ReportDataSourceSample  extends  ReportDataSource {   
    •   
    •   private  List docs =  new  ArrayList();   
    •   
    •   private   int  index = - 1 ;   
    •   
    •   public  ReportDataSourceSample() {   
    •    for  ( int  i =  0 ; i <  10 ; i++) {   
    •    Document doc =  new  Document( "ViewTimes is:"  + i, i);   
    •     this .docs.add(doc);   
    •   }   
    •  }   
    •   
    •   // 内部类,作为demo时使用   
    •   private   class  Document {   
    •    private  String name;   
    •   
    •    private   int  viewTimes;   
    •   
    •    public  String getName() {   
    •     return  name;   
    •   }   
    •   
    •    public   void  setName(String name) {   
    •     this .name = name;   
    •   }   
    •   
    •    public   int  getViewTimes() {   
    •     return  viewTimes;   
    •   }   
    •   
    •    public   void  setViewTimes( int  viewTimes) {   
    •     this .viewTimes = viewTimes;   
    •   }   
    •   
    •    public  Document() {   
    •   }   
    •   
    •    public  Document(String name,  int  viewTimes) {   
    •     this .name = name;   
    •     this .viewTimes = viewTimes;   
    •   }   
    •  }   
    •   
    •   public  List getDocs() {   
    •    return  docs;   
    •  }   
    •   
    •   public   void  setDocs(List docs) {   
    •    this .docs = docs;   
    •  }   
    •   
    •   @Override   
    •   public  Object getFieldValue(JRField jrField)  throws  JRException {   
    •   
    •   String fieldName = jrField.getName();   
    •   Document doc =  this .docs.get(index);   
    •    if  ( "name" .equals(fieldName)) {   
    •     return  doc.getName();   
    •   }   
    •    if  ( "viewTimes" .equals(fieldName)) {   
    •     return  doc.getViewTimes();   
    •   }   
    •    return   null ;   
    •  }   
    •   
    •   @Override   
    •   public   boolean  next()  throws  JRException {   
    •   index++;   
    •    return  (index <  this .docs.size());   
    •  }   
    • }   
    •   
java 代码

以上的例子应当很清楚的写明了如何生成数据源。
对于数据源的填充,笔者使用了二个类,分别用来对应使用Connction及JavaBean Collection进行填充。

java 代码
 
    • /**  
    •  * @copyRight Beijing Tsing-Tech Reachway Software Co.,Ltd.  
    •  * @author Jimmy.Shine 2007-5-12  
    •  */   
    • package  cn.com.reachway.framework.report.jasperPrint;   
    •   
    • import  java.io.File;   
    • import  java.sql.Connection;   
    • import  java.util.Map;   
    •   
    • import  net.sf.jasperreports.engine.JRException;   
    • import  net.sf.jasperreports.engine.JasperFillManager;   
    • import  net.sf.jasperreports.engine.JasperPrint;   
    • import  net.sf.jasperreports.engine.JasperReport;   
    • import  net.sf.jasperreports.engine.util.JRLoader;   
    • import  cn.com.reachway.framework.exception.JasperReportException;   
    •   
    • /**  
    •  * 使用报表模板及数据等来生成JapserPrint  
    •  */   
    • public   class  JasperPrintWithConnection {   
    •   /** 传入的参数 */   
    •   private  Map params;   
    •   /** 模板文件的地址 */   
    •   private  String reportFilePath;   
    •   /** JDBC connection */   
    •   private  Connection con;   
    •   
    •   public  Connection getCon() {   
    •    return  con;   
    •  }   
    •   
    •   public   void  setCon(Connection con) {   
    •    this .con = con;   
    •  }   
    •   
    •   public  Map getParams() {   
    •    return  params;   
    •  }   
    •   
    •   public   void  setParams(Map params) {   
    •    this .params = params;   
    •  }   
    •   
    •   public  String getReportFilePath() {   
    •    return  reportFilePath;   
    •  }   
    •   
    •   public   void  setReportFilePath(String reportFilePath)  throws  JasperReportException {   
    •    if  (reportFilePath ==  null  || !reportFilePath.endsWith( ".jasper" ))   
    •     throw   new  JasperReportException( "您传入的模板文件格式不对,请传入以.jasper为后缀的文件!" );   
    •    this .reportFilePath = reportFilePath;   
    •  }   
    •   
    •   public  JasperPrintWithConnection() {   
    •    super ();   
    •  }   
    •   
    •   public  JasperPrintWithConnection(String reportFilePath, Map params, Connection con)  throws  JasperReportException {   
    •    if  (reportFilePath ==  null  || !reportFilePath.endsWith( ".jasper" ))   
    •     throw   new  JasperReportException( "模板文件格式不对,请传入以.jasper为后缀的文件!" );   
    •    if  (con ==  null )   
    •     throw   new  JasperReportException( "Conncetion不应当为null!" );   
    •    this .setReportFilePath(reportFilePath);   
    •    this .setParams(params);   
    •    this .setCon(con);   
    •  }   
    •     
    •   /**  
    •   * 取得JasperPrint  
    •   * @return  
    •   * @throws JasperReportException  
    •   */   
    •   public  JasperPrint getJasperPrint()  throws  JasperReportException {   
    •   File reportFile =  new  File( this .reportFilePath);   
    •    if  (!reportFile.exists())   
    •     throw   new  JasperReportException( "传入的模板文件不存在!" );   
    •   
    •    try  {   
    •     // Load编译好的模板   
    •    JasperReport jasperReport = (JasperReport) JRLoader.loadObject(reportFile.getPath());   
    •     // 进行数据填充   
    •    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,  this .params,  this .con);   
    •     return  jasperPrint;   
    •   
    •   }  catch  (JRException jre) {   
    •    jre.printStackTrace();   
    •     throw   new  JasperReportException( "在进行数据填充时发生了错误中,请检查是否是数据库连接错误或者是用来填充的参数map有误!" );   
    •   }   
    •   
    •  }   
    • }   
    •   

 
    • /**  
    •  * @copyRight Beijing Tsing-Tech Reachway Software Co.,Ltd.  
    •  * @author Jimmy.Shine 2007-5-14  
    •  */   
    • package  cn.com.reachway.framework.report.jasperPrint;   
    •   
    • import  java.io.File;   
    • import  java.util.Map;   
    •   
    • import  net.sf.jasperreports.engine.JRDataSource;   
    • import  net.sf.jasperreports.engine.JRException;   
    • import  net.sf.jasperreports.engine.JasperFillManager;   
    • import  net.sf.jasperreports.engine.JasperPrint;   
    • import  net.sf.jasperreports.engine.JasperReport;   
    • import  net.sf.jasperreports.engine.util.JRLoader;   
    • import  cn.com.reachway.framework.exception.JasperReportException;   
    •   
    • /**  
    •  *   
    •  */   
    • public   class  JasperPrintWithDataSource {   
    •   /** 传入的参数 */   
    •   private  Map params;   
    •   /** 模板文件的地址 */   
    •   private  String reportFilePath;   
    •   /** dataSrouce */   
    •   private  JRDataSource dataSource;   
    •   
    •   public  JRDataSource getDataSource() {   
    •    return  dataSource;   
    •  }   
    •   
    •   public   void  setDataSource(JRDataSource dataSource) {   
    •    this .dataSource = dataSource;   
    •  }   
    •   
    •   public  Map getParams() {   
    •    return  params;   
    •  }   
    •   
    •   public   void  setParams(Map params) {   
    •    this .params = params;   
    •  }   
    •   
    •   public  String getReportFilePath() {   
    •    return  reportFilePath;   
    •  }   
    •   
    •   public   void  setReportFilePath(String reportFilePath)  throws  JasperReportException {   
    •    if  (reportFilePath ==  null  || !reportFilePath.endsWith( ".jasper" ))   
    •     throw   new  JasperReportException( "您传入的模板文件格式不对,请传入以.jasper为后缀的文件!" );   
    •    this .reportFilePath = reportFilePath;   
    •  }   
    •   
    •   public  JasperPrintWithDataSource() {   
    •    super ();   
    •  }   
    •   
    •   public  JasperPrintWithDataSource(String reportFilePath, Map params, JRDataSource dataSource)   
    •     throws  JasperReportException {   
    •    if  (reportFilePath ==  null  || !reportFilePath.endsWith( ".jasper" ))   
    •     throw   new  JasperReportException( "模板文件格式不对,请传入以.jasper为后缀的文件!" );   
    •    if  (dataSource ==  null )   
    •     throw   new  JasperReportException( "DataSource不应当为null!" );   
    •    this .setReportFilePath(reportFilePath);   
    •    this .setParams(params);   
    •    this .setDataSource(dataSource);   
    •  }   
    •   /**  
    •   * 取得JasperPrint  
    •   * @return  
    •   * @throws JasperReportException  
    •   */   
    •   public  JasperPrint getJasperPrint()  throws  JasperReportException {   
    •   File reportFile =  new  File( this .reportFilePath);   
    •    if  (!reportFile.exists())   
    •     throw   new  JasperReportException( "传入的模板文件不存在!" );   
    •   
    •    try  {   
    •     // Load编译好的模板   
    •    JasperReport jasperReport = (JasperReport) JRLoader.loadObject(reportFile.getPath());   
    •     // 进行数据填充   
    •    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,  this .params,  this .dataSource);   
    •     return  jasperPrint;   
    •   
    •   }  catch  (JRException jre) {   
    •    jre.printStackTrace();   
    •     throw   new  JasperReportException( "在进行数据填充时发生了错误中,请检查是否是数据库连接错误或者是用来填充的参数map有误!" );   
    •   }   
    •   
    •  }   
    • }   
    •   
java 代码

其中使用的JasperReportException为笔者定义的异常,用来统一处理报表异常。

5、报表产生
报表产生是程序中最终可见的一部分,在jasperReport的demo中,大部分中使用了jasperReport的 net.sf.jasperreports.j2ee.servlets.*中的类来生成。其实这也算是开源的产品的一个问题,其实 jasperReport提供的report的工具,只能算是demo级别的,不能算是产品级别的。相信很多的朋友在使用的时候就碰上无法生成的问题。笔 者在此基础上封装了一下。
具体参见以下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值