JasperReport报表设计总结

翻译|其它|编辑:郝浩|2007-09-05 11:23:56.000|阅读 1518 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

为了开发报表,已经拜读了一大堆的资料,其中大部分是重复的。可以看得出,国人还是比较热衷于  copypaste  的工作。所以找了一大堆的资料都是相同的,或者可以用一个词来形容,换汤不换药的。
有必要对于  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  必须。

2iReport  的安装

这个很简单,直接下一步就可以了。

3、使用  iReport  生成 .jasper  文件
   .jasper  是经过编译的  japserReport  模板,即  .jrxml  编译后的。
   对于  iReport  的使用网络上已经有了详细的中文的文档,具体可以下载附件查看。使用  .jasper  文件可以避免在系统中再进行编译,增加系统的压力。

4、数据填充
   数据填充是相对于比较重要的一步,数据填充的目的是为了将数据填充进去,生成一个  JapserPrint  对象。笔者在之前已经阐述过,现在主要是基于关系型数据库(比较简单的,没有权限控制的),以及基于  JavaBean Collection  进行数据填充。进行数据填充的基本就是一定要实现  JRDataSourceJRDataSource  定义了二个方法,一个是指针移动的方法next(),另一个是取值的  getFieldValue()方法,用来取值填充。
   对于关系型数据库,即直接利用数据库的表来生成报表的,只需要传入一个  Java Connection  即可。JasperReport  已经有了个默认的实现的  JRDataSource  的接口了。对于  Java Conncetion  的获得,笔者建议使用工厂方法或者使用  Spring  方式来获得。可以参照笔者写的如下:

java 代码

1.      /**  

2.       * @copyRight Beijing Tsing-Tech Reachway Software Co.,Ltd.  

3.       * @author Jimmy.Shine 2007-5-11  

4.       */  

5.      package cn.com.reachway.framework.report;   

6.        

7.      import java.sql.Connection;   

8.      import java.sql.DriverManager;   

9.        

10.  import cn.com.reachway.framework.exception.JasperReportException;   

11.    

12.  /**  

13.   * Used for get a JDBC connection for Jasper Report  

14.   */  

15.  public class JDBCConnection {   

16.   /**  

17.    * Which Jdbc driver were used. Like: "net.sourceforge.jtds.jdbc.Driver"  

18.    */  

19.   private String jdbcDriver;   

20.   /**  

21.    * The jdbc url,define which database server,which db. Like:  

22.    * "jdbc:jtds:sqlserver://192.168.1.50:1433;DatabaseName=JAVA5;SelectMethod=Cursor"  

23.    */  

24.   private String jdbcUrl;   

25.    

26.   private String dbUser;   

27.    

28.   private String dbPassword;   

29.    

30.   public String getDbPassword() {   

31.    return dbPassword;   

32.   }   

33.    

34.   public void setDbPassword(String dbPassword) {   

35.    this.dbPassword = dbPassword;   

36.   }   

37.    

38.   public String getDbUser() {   

39.    return dbUser;   

40.   }   

41.    

42.   public void setDbUser(String dbUser) {   

43.    this.dbUser = dbUser;   

44.   }   

45.    

46.   public String getJdbcDriver() {   

47.    return jdbcDriver;   

48.   }   

49.    

50.   public void setJdbcDriver(String jdbcDriver) {   

51.    this.jdbcDriver = jdbcDriver;   

52.   }   

53.    

54.   public String getJdbcUrl() {   

55.    return jdbcUrl;   

56.   }   

57.    

58.   public void setJdbcUrl(String jdbcUrl) {   

59.    this.jdbcUrl = jdbcUrl;   

60.   }   

61.    

62.   public JDBCConnection() {   

63.    super();   

64.   }   

65.   /**  

66.    * Get the Connection   

67.    * @return connection  

68.    * @throws JasperReportException  

69.    */  

70.   public Connection getConnection() throws JasperReportException {   

71.    Connection con;   

72.    try {   

73.     check();   

74.     Class.forName(this.jdbcDriver);   

75.     con = DriverManager.getConnection(this.jdbcUrl, this.dbUser, this.dbPassword);   

76.     return con;   

77.    } catch (Exception e) {   

78.     e.printStackTrace();   

79.     throw new JasperReportException("Get JDBC Connection Error");   

80.    }   

81.   }   

82.      

83.   /**  

84.    * Check the Configure  

85.    * @throws JasperReportException  

86.    */  

87.   private void check() throws JasperReportException {   

88.    if (this.jdbcDriver == null || this.jdbcDriver.equals("") || this.jdbcUrl == null || this.jdbcUrl.equals("")   

89.      || this.dbUser == null || this.dbUser.equals("") || this.dbPassword == null) {   

90.     throw new JasperReportException("Jdbc Configure error!");   

91.    }   

92.   }   

93.    

94.  }   

95.    

 

java  代码

1.      /**  

2.       * @copyRight Beijing Tsing-Tech Reachway Software Co.,Ltd.  

3.       * @author Jimmy.Shine 2007-5-14  

4.       */  

5.      package cn.com.reachway.framework.report.dataSource;   

6.        

7.      import net.sf.jasperreports.engine.JRDataSource;   

8.      import net.sf.jasperreports.engine.JRException;   

9.      import net.sf.jasperreports.engine.JRField;   

10.    

11.  /**  

12.   * 报表的  dataSource  的基类,所有利用  DataSource  产生报表的继承此类  

13.   */  

14.  public abstract class ReportDataSource implements JRDataSource {   

15.    

16.   /**  

17.    * 取值  

18.    */  

19.   public abstract Object getFieldValue(JRField jrField) throws JRException;   

20.    

21.   /**  

22.    * 指针移动  

23.    */  

24.   public abstract boolean next() throws JRException;   

25.    

26.  }   

27.    

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

1.      /**  

2.       * @copyRight Beijing Tsing-Tech Reachway Software Co.,Ltd.  

3.       * @author Jimmy.Shine 2007-5-14  

4.       */  

5.      package cn.com.reachway.framework.report.dataSource;   

6.        

7.      import java.util.ArrayList;   

8.      import java.util.List;   

9.        

10.  import net.sf.jasperreports.engine.JRException;   

11.  import net.sf.jasperreports.engine.JRField;   

12.    

13.  /**  

14.   * 利用JavaBean Collection生成ReportDataSource的例子  

15.   */  

16.  public class ReportDataSourceSample extends ReportDataSource {   

17.    

18.   private List docs = new ArrayList();   

19.    

20.   private int index = -1;   

21.    

22.   public ReportDataSourceSample() {   

23.    for (int i = 0; i < 10; i++) {   

24.     Document doc = new Document("ViewTimes is:" + i, i);   

25.     this.docs.add(doc);   

26.    }   

27.   }   

28.    

29.   // 内部类,作为demo时使用   

30.   private class Document {   

31.    private String name;   

32.    

33.    private int viewTimes;   

34.    

35.    public String getName() {   

36.     return name;   

37.    }   

38.    

39.    public void setName(String name) {   

40.     this.name = name;   

41.    }   

42.    

43.    public int getViewTimes() {   

44.     return viewTimes;   

45.    }   

46.    

47.    public void setViewTimes(int viewTimes) {   

48.     this.viewTimes = viewTimes;   

49.    }   

50.    

51.    public Document() {   

52.    }   

53.    

54.    public Document(String name, int viewTimes) {   

55.     this.name = name;   

56.     this.viewTimes = viewTimes;   

57.    }   

58.   }   

59.    

60.   public List getDocs() {   

61.    return docs;   

62.   }   

63.    

64.   public void setDocs(List docs) {   

65.    this.docs = docs;   

66.   }   

67.    

68.   @Override  

69.   public Object getFieldValue(JRField jrField) throws JRException {   

70.    

71.    String fieldName = jrField.getName();   

72.    Document doc = this.docs.get(index);   

73.    if ("name".equals(fieldName)) {   

74.     return doc.getName();   

75.    }   

76.    if ("viewTimes".equals(fieldName)) {   

77.     return doc.getViewTimes();   

78.    }   

79.    return null;   

80.   }   

81.    

82.   @Override  

83.   public boolean next() throws JRException {   

84.    index++;   

85.    return (index < this.docs.size());   

86.   }   

87.  }   

88.    

java 代码

以上的例子应当很清楚的写明了如何生成数据源。

对于数据源的填充,笔者使用了二个类,分别用来对应使用  Connction    JavaBean Collection  进行填充。

java 代码

1.      /**  

2.       * @copyRight Beijing Tsing-Tech Reachway Software Co.,Ltd.  

3.       * @author Jimmy.Shine 2007-5-12  

4.       */  

5.      package cn.com.reachway.framework.report.jasperPrint;   

6.        

7.      import java.io.File;   

8.      import java.sql.Connection;   

9.      import java.util.Map;   

10.    

11.  import net.sf.jasperreports.engine.JRException;   

12.  import net.sf.jasperreports.engine.JasperFillManager;   

13.  import net.sf.jasperreports.engine.JasperPrint;   

14.  import net.sf.jasperreports.engine.JasperReport;   

15.  import net.sf.jasperreports.engine.util.JRLoader;   

16.  import cn.com.reachway.framework.exception.JasperReportException;   

17.    

18.  /**  

19.   * 使用报表模板及数据等来生成  JapserPrint  

20.   */  

21.  public class JasperPrintWithConnection {   

22.   /** 传入的参数 */  

23.   private Map params;   

24.   /** 模板文件的地址 */  

25.   private String reportFilePath;   

26.   /** JDBC connection */  

27.   private Connection con;   

28.    

29.   public Connection getCon() {   

30.    return con;   

31.   }   

32.    

33.   public void setCon(Connection con) {   

34.    this.con = con;   

35.   }   

36.    

37.   public Map getParams() {   

38.    return params;   

39.   }   

40.    

41.   public void setParams(Map params) {   

42.    this.params = params;   

43.   }   

44.    

45.   public String getReportFilePath() {   

46.    return reportFilePath;   

47.   }   

48.    

49.   public void setReportFilePath(String reportFilePath) throws JasperReportException {   

50.    if (reportFilePath == null || !reportFilePath.endsWith(".jasper"))   

51.     throw new JasperReportException("您传入的模板文件格式不对,请传入以.jasper  为后缀的文件!");   

52.    this.reportFilePath = reportFilePath;   

53.   }   

54.    

55.   public JasperPrintWithConnection() {   

56.    super();   

57.   }   

58.    

59.   public JasperPrintWithConnection(String reportFilePath, Map params, Connection con) throws JasperReportException {   

60.    if (reportFilePath == null || !reportFilePath.endsWith(".jasper"))   

61.     throw new JasperReportException("模板文件格式不对,请传入以 .jasper  为后缀的文件!");   

62.    if (con == null)   

63.     throw new JasperReportException("Conncetion  不应当为null!");   

64.    this.setReportFilePath(reportFilePath);   

65.    this.setParams(params);   

66.    this.setCon(con);   

67.   }   

68.      

69.   /**  

70.    * 取得JasperPrint  

71.    * @return  

72.    * @throws JasperReportException  

73.    */  

74.   public JasperPrint getJasperPrint() throws JasperReportException {   

75.    File reportFile = new File(this.reportFilePath);   

76.    if (!reportFile.exists())   

77.     throw new JasperReportException("传入的模板文件不存在!");   

78.    

79.    try {   

80.     // Load编译好的模板   

81.     JasperReport jasperReport = (JasperReport) JRLoader.loadObject(reportFile.getPath());   

82.     // 进行数据填充   

83.     JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, this.params, this.con);   

84.     return jasperPrint;   

85.    

86.    } catch (JRException jre) {   

87.     jre.printStackTrace();   

88.     throw new JasperReportException("在进行数据填充时发生了错误中,请检查是否是数据库连接错误或者是用来填充的参数  map  有误!");   

89.    }   

90.    

91.   }   

92.  }   

93.    

1.      /**  

2.       * @copyRight Beijing Tsing-Tech Reachway Software Co.,Ltd.  

3.       * @author Jimmy.Shine 2007-5-14  

4.       */  

5.      package cn.com.reachway.framework.report.jasperPrint;   

6.        

7.      import java.io.File;   

8.      import java.util.Map;   

9.        

10.  import net.sf.jasperreports.engine.JRDataSource;   

11.  import net.sf.jasperreports.engine.JRException;   

12.  import net.sf.jasperreports.engine.JasperFillManager;   

13.  import net.sf.jasperreports.engine.JasperPrint;   

14.  import net.sf.jasperreports.engine.JasperReport;   

15.  import net.sf.jasperreports.engine.util.JRLoader;   

16.  import cn.com.reachway.framework.exception.JasperReportException;   

17.    

18.  /**  

19.   *   

20.   */  

21.  public class JasperPrintWithDataSource {   

22.   /** 传入的参数 */  

23.   private Map params;   

24.   /** 模板文件的地址 */  

25.   private String reportFilePath;   

26.   /** dataSrouce */  

27.   private JRDataSource dataSource;   

28.    

29.   public JRDataSource getDataSource() {   

30.    return dataSource;   

31.   }   

32.    

33.   public void setDataSource(JRDataSource dataSource) {   

34.    this.dataSource = dataSource;   

35.   }   

36.    

37.   public Map getParams() {   

38.    return params;   

39.   }   

40.    

41.   public void setParams(Map params) {   

42.    this.params = params;   

43.   }   

44.    

45.   public String getReportFilePath() {   

46.    return reportFilePath;   

47.   }   

48.    

49.   public void setReportFilePath(String reportFilePath) throws JasperReportException {   

50.    if (reportFilePath == null || !reportFilePath.endsWith(".jasper"))   

51.     throw new JasperReportException("您传入的模板文件格式不对,请传入以  .jasper  为后缀的文件!");   

52.    this.reportFilePath = reportFilePath;   

53.   }   

54.    

55.   public JasperPrintWithDataSource() {   

56.    super();   

57.   }   

58.    

59.   public JasperPrintWithDataSource(String reportFilePath, Map params, JRDataSource dataSource)   

60.     throws JasperReportException {   

61.    if (reportFilePath == null || !reportFilePath.endsWith(".jasper"))   

62.     throw new JasperReportException("模板文件格式不对,请传入以 .jasper  为后缀的文件!");   

63.    if (dataSource == null)   

64.     throw new JasperReportException("DataSource  不应当为  null!");   

65.    this.setReportFilePath(reportFilePath);   

66.    this.setParams(params);   

67.    this.setDataSource(dataSource);   

68.   }   

69.   /**  

70.    * 取得  JasperPrint  

71.    * @return  

72.    * @throws JasperReportException  

73.    */  

74.   public JasperPrint getJasperPrint() throws JasperReportException {   

75.    File reportFile = new File(this.reportFilePath);   

76.    if (!reportFile.exists())   

77.     throw new JasperReportException("传入的模板文件不存在!");   

78.    

79.    try {   

80.     // Load  编译好的模板   

81.     JasperReport jasperReport = (JasperReport) JRLoader.loadObject(reportFile.getPath());   

82.     // 进行数据填充   

83.     JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, this.params, this.dataSource);   

84.     return jasperPrint;   

85.    

86.    } catch (JRException jre) {   

87.     jre.printStackTrace();   

88.     throw new JasperReportException("在进行数据填充时发生了错误中,请检查是否是数据库连接错误或者是用来填充的参数  map  有误!");   

89.    }   

90.    

91.   }   

92.  }   

93.    

java 代码

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

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

Java  代码

1.      /**  

2.       * @copyRight Beijing Tsing-Tech Reachway Software Co.,Ltd.  

3.       * @author Jimmy.Shine 2007-5-12  

4.       */  

5.      package cn.com.reachway.framework.report.export;   

6.        

7.      import java.io.IOException;   

8.      import java.io.PrintWriter;   

9.      import java.sql.Connection;   

10.  import java.util.Map;   

11.    

12.  import javax.servlet.http.HttpServletRequest;   

13.  import javax.servlet.http.HttpServletResponse;   

14.    

15.  import net.sf.jasperreports.engine.JRDataSource;   

16.  import net.sf.jasperreports.engine.JRExporterParameter;   

17.  import net.sf.jasperreports.engine.JasperPrint;   

18.  import net.sf.jasperreports.engine.export.JRHtmlExporter;   

19.  import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;   

20.  import net.sf.jasperreports.j2ee.servlets.ImageServlet;   

21.  import cn.com.reachway.framework.exception.JasperReportException;   

22.  import cn.com.reachway.framework.report.jasperPrint.JasperPrintWithConnection;   

23.  import cn.com.reachway.framework.report.jasperPrint.JasperPrintWithDataSource;   

24.    

25.  /**  

26.   * 利用报表生成  HTML  格式报表  

27.   */  

28.  public class HTMLExport {   

29.    

30.   /**  

31.    * 导出报表  

32.    *   

33.    * @param request  

34.    * @param response  

35.    * @param reportFilePath  

36.    * @param params  

37.    * @param con  

38.    * @throws JasperReportException  

39.    */  

40.   public void export(HttpServletRequest request, HttpServletResponse response, String reportFilePath, Map params,   

41.     Connection con) throws JasperReportException {   

42.    try {   

43.     PrintWriter out = response.getWriter();   

44.     try {   

45.      response.setContentType("text/html;charset=UTF-8");   

46.      JasperPrint jasperPrint = new JasperPrintWithConnection(reportFilePath, params, con).getJasperPrint();   

47.      // 使用JRHtmlExproter导出  Html  格式   

48.      JRHtmlExporter exporter = new JRHtmlExporter();   

49.      request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);   

50.      exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);   

51.      exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);   

52.      exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "./servlets/image?image=");   

53.      exporter.setParameter(JRExporterParameter.CHARACTER_ENCODING, "UTF-8");   

54.      // 导出   

55.      exporter.exportReport();   

56.     } catch (Exception e) {   

57.      e.printStackTrace();   

58.      throw new JasperReportException("在导出  Html  格式报表时发生错误!");   

59.     } finally {   

60.      if (out != null) {   

61.       try {   

62.        out.close();   

63.       } catch (Exception e) {   

64.       }   

65.      }   

66.     }   

67.    } catch (IOException ioe) {   

68.     ioe.printStackTrace();   

69.     throw new JasperReportException("  Response  中取得  P


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:JavaEye

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP