`
thecloud
  • 浏览: 884840 次
文章分类
社区版块
存档分类
最新评论

JasperReport报表设计总结

 
阅读更多
首先,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 代码
  1. /**
  2. *@copyRightBeijingTsing-TechReachwaySoftwareCo.,Ltd.
  3. *@authorJimmy.Shine2007-5-11
  4. */
  5. packagecn.com.reachway.framework.report;
  6. importjava.sql.Connection;
  7. importjava.sql.DriverManager;
  8. importcn.com.reachway.framework.exception.JasperReportException;
  9. /**
  10. *UsedforgetaJDBCconnectionforJasperReport
  11. */
  12. publicclassJDBCConnection{
  13. /**
  14. *WhichJdbcdriverwereused.Like:"net.sourceforge.jtds.jdbc.Driver"
  15. */
  16. privateStringjdbcDriver;
  17. /**
  18. *Thejdbcurl,definewhichdatabaseserver,whichdb.Like:
  19. *"jdbc:jtds:sqlserver://192.168.1.50:1433;DatabaseName=JAVA5;SelectMethod=Cursor"
  20. */
  21. privateStringjdbcUrl;
  22. privateStringdbUser;
  23. privateStringdbPassword;
  24. publicStringgetDbPassword(){
  25. returndbPassword;
  26. }
  27. publicvoidsetDbPassword(StringdbPassword){
  28. this.dbPassword=dbPassword;
  29. }
  30. publicStringgetDbUser(){
  31. returndbUser;
  32. }
  33. publicvoidsetDbUser(StringdbUser){
  34. this.dbUser=dbUser;
  35. }
  36. publicStringgetJdbcDriver(){
  37. returnjdbcDriver;
  38. }
  39. publicvoidsetJdbcDriver(StringjdbcDriver){
  40. this.jdbcDriver=jdbcDriver;
  41. }
  42. publicStringgetJdbcUrl(){
  43. returnjdbcUrl;
  44. }
  45. publicvoidsetJdbcUrl(StringjdbcUrl){
  46. this.jdbcUrl=jdbcUrl;
  47. }
  48. publicJDBCConnection(){
  49. super();
  50. }
  51. /**
  52. *GettheConnection
  53. *@returnconnection
  54. *@throwsJasperReportException
  55. */
  56. publicConnectiongetConnection()throwsJasperReportException{
  57. Connectioncon;
  58. try{
  59. check();
  60. Class.forName(this.jdbcDriver);
  61. con=DriverManager.getConnection(this.jdbcUrl,this.dbUser,this.dbPassword);
  62. returncon;
  63. }catch(Exceptione){
  64. e.printStackTrace();
  65. thrownewJasperReportException("GetJDBCConnectionError");
  66. }
  67. }
  68. /**
  69. *ChecktheConfigure
  70. *@throwsJasperReportException
  71. */
  72. privatevoidcheck()throwsJasperReportException{
  73. if(this.jdbcDriver==null||this.jdbcDriver.equals("")||this.jdbcUrl==null||this.jdbcUrl.equals("")
  74. ||this.dbUser==null||this.dbUser.equals("")||this.dbPassword==null){
  75. thrownewJasperReportException("JdbcConfigureerror!");
  76. }
  77. }
  78. }


java 代码
  1. /**
  2. *@copyRightBeijingTsing-TechReachwaySoftwareCo.,Ltd.
  3. *@authorJimmy.Shine2007-5-14
  4. */
  5. packagecn.com.reachway.framework.report.dataSource;
  6. importnet.sf.jasperreports.engine.JRDataSource;
  7. importnet.sf.jasperreports.engine.JRException;
  8. importnet.sf.jasperreports.engine.JRField;
  9. /**
  10. *报表的dataSource的基类,所有利用DataSource产生报表的继承此类
  11. */
  12. publicabstractclassReportDataSourceimplementsJRDataSource{
  13. /**
  14. *取值
  15. */
  16. publicabstractObjectgetFieldValue(JRFieldjrField)throwsJRException;
  17. /**
  18. *指针移动
  19. */
  20. publicabstractbooleannext()throwsJRException;
  21. }
  这样可以共用配置文件中的jdbc连接的相关参数。
  对于其它的数据源,JavaBean Collection,笔者采用了一个抽象类,使用抽象类的目的,是为了使开发者尽可能不用直接接触jasperReport(此为笔者自己的方式,笔者是PM,为了考虑底下的人的开发)。以下为抽象类以及笔者提供的一个sample:
  1. /**
  2. *@copyRightBeijingTsing-TechReachwaySoftwareCo.,Ltd.
  3. *@authorJimmy.Shine2007-5-14
  4. */
  5. packagecn.com.reachway.framework.report.dataSource;
  6. importjava.util.ArrayList;
  7. importjava.util.List;
  8. importnet.sf.jasperreports.engine.JRException;
  9. importnet.sf.jasperreports.engine.JRField;
  10. /**
  11. *利用JavaBeanCollection生成ReportDataSource的例子
  12. */
  13. publicclassReportDataSourceSampleextendsReportDataSource{
  14. privateListdocs=newArrayList();
  15. privateintindex=-1;
  16. publicReportDataSourceSample(){
  17. for(inti=0;i<10;i++){
  18. Documentdoc=newDocument("ViewTimesis:"+i,i);
  19. this.docs.add(doc);
  20. }
  21. }
  22. //内部类,作为demo时使用
  23. privateclassDocument{
  24. privateStringname;
  25. privateintviewTimes;
  26. publicStringgetName(){
  27. returnname;
  28. }
  29. publicvoidsetName(Stringname){
  30. this.name=name;
  31. }
  32. publicintgetViewTimes(){
  33. returnviewTimes;
  34. }
  35. publicvoidsetViewTimes(intviewTimes){
  36. this.viewTimes=viewTimes;
  37. }
  38. publicDocument(){
  39. }
  40. publicDocument(Stringname,intviewTimes){
  41. this.name=name;
  42. this.viewTimes=viewTimes;
  43. }
  44. }
  45. publicListgetDocs(){
  46. returndocs;
  47. }
  48. publicvoidsetDocs(Listdocs){
  49. this.docs=docs;
  50. }
  51. @Override
  52. publicObjectgetFieldValue(JRFieldjrField)throwsJRException{
  53. StringfieldName=jrField.getName();
  54. Documentdoc=this.docs.get(index);
  55. if("name".equals(fieldName)){
  56. returndoc.getName();
  57. }
  58. if("viewTimes".equals(fieldName)){
  59. returndoc.getViewTimes();
  60. }
  61. returnnull;
  62. }
  63. @Override
  64. publicbooleannext()throwsJRException{
  65. index++;
  66. return(index<this.docs.size());
  67. }
  68. }
java 代码

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

java 代码
  1. /**
  2. *@copyRightBeijingTsing-TechReachwaySoftwareCo.,Ltd.
  3. *@authorJimmy.Shine2007-5-12
  4. */
  5. packagecn.com.reachway.framework.report.jasperPrint;
  6. importjava.io.File;
  7. importjava.sql.Connection;
  8. importjava.util.Map;
  9. importnet.sf.jasperreports.engine.JRException;
  10. importnet.sf.jasperreports.engine.JasperFillManager;
  11. importnet.sf.jasperreports.engine.JasperPrint;
  12. importnet.sf.jasperreports.engine.JasperReport;
  13. importnet.sf.jasperreports.engine.util.JRLoader;
  14. importcn.com.reachway.framework.exception.JasperReportException;
  15. /**
  16. *使用报表模板及数据等来生成JapserPrint
  17. */
  18. publicclassJasperPrintWithConnection{
  19. /**传入的参数*/
  20. privateMapparams;
  21. /**模板文件的地址*/
  22. privateStringreportFilePath;
  23. /**JDBCconnection*/
  24. privateConnectioncon;
  25. publicConnectiongetCon(){
  26. returncon;
  27. }
  28. publicvoidsetCon(Connectioncon){
  29. this.con=con;
  30. }
  31. publicMapgetParams(){
  32. returnparams;
  33. }
  34. publicvoidsetParams(Mapparams){
  35. this.params=params;
  36. }
  37. publicStringgetReportFilePath(){
  38. returnreportFilePath;
  39. }
  40. publicvoidsetReportFilePath(StringreportFilePath)throwsJasperReportException{
  41. if(reportFilePath==null||!reportFilePath.endsWith(".jasper"))
  42. thrownewJasperReportException("您传入的模板文件格式不对,请传入以.jasper为后缀的文件!");
  43. this.reportFilePath=reportFilePath;
  44. }
  45. publicJasperPrintWithConnection(){
  46. super();
  47. }
  48. publicJasperPrintWithConnection(StringreportFilePath,Mapparams,Connectioncon)throwsJasperReportException{
  49. if(reportFilePath==null||!reportFilePath.endsWith(".jasper"))
  50. thrownewJasperReportException("模板文件格式不对,请传入以.jasper为后缀的文件!");
  51. if(con==null)
  52. thrownewJasperReportException("Conncetion不应当为null!");
  53. this.setReportFilePath(reportFilePath);
  54. this.setParams(params);
  55. this.setCon(con);
  56. }
  57. /**
  58. *取得JasperPrint
  59. *@return
  60. *@throwsJasperReportException
  61. */
  62. publicJasperPrintgetJasperPrint()throwsJasperReportException{
  63. FilereportFile=newFile(this.reportFilePath);
  64. if(!reportFile.exists())
  65. thrownewJasperReportException("传入的模板文件不存在!");
  66. try{
  67. //Load编译好的模板
  68. JasperReportjasperReport=(JasperReport)JRLoader.loadObject(reportFile.getPath());
  69. //进行数据填充
  70. JasperPrintjasperPrint=JasperFillManager.fillReport(jasperReport,this.params,this.con);
  71. returnjasperPrint;
  72. }catch(JRExceptionjre){
  73. jre.printStackTrace();
  74. thrownewJasperReportException("在进行数据填充时发生了错误中,请检查是否是数据库连接错误或者是用来填充的参数map有误!");
  75. }
  76. }
  77. }
  1. /**
  2. *@copyRightBeijingTsing-TechReachwaySoftwareCo.,Ltd.
  3. *@authorJimmy.Shine2007-5-14
  4. */
  5. packagecn.com.reachway.framework.report.jasperPrint;
  6. importjava.io.File;
  7. importjava.util.Map;
  8. importnet.sf.jasperreports.engine.JRDataSource;
  9. importnet.sf.jasperreports.engine.JRException;
  10. importnet.sf.jasperreports.engine.JasperFillManager;
  11. importnet.sf.jasperreports.engine.JasperPrint;
  12. importnet.sf.jasperreports.engine.JasperReport;
  13. importnet.sf.jasperreports.engine.util.JRLoader;
  14. importcn.com.reachway.framework.exception.JasperReportException;
  15. /**
  16. *
  17. */
  18. publicclassJasperPrintWithDataSource{
  19. /**传入的参数*/
  20. privateMapparams;
  21. /**模板文件的地址*/
  22. privateStringreportFilePath;
  23. /**dataSrouce*/
  24. privateJRDataSourcedataSource;
  25. publicJRDataSourcegetDataSource(){
  26. returndataSource;
  27. }
  28. publicvoidsetDataSource(JRDataSourcedataSource){
  29. this.dataSource=dataSource;
  30. }
  31. publicMapgetParams(){
  32. returnparams;
  33. }
  34. publicvoidsetParams(Mapparams){
  35. this.params=params;
  36. }
  37. publicStringgetReportFilePath(){
  38. returnreportFilePath;
  39. }
  40. publicvoidsetReportFilePath(StringreportFilePath)throwsJasperReportException{
  41. if(reportFilePath==null||!reportFilePath.endsWith(".jasper"))
  42. thrownewJasperReportException("您传入的模板文件格式不对,请传入以.jasper为后缀的文件!");
  43. this.reportFilePath=reportFilePath;
  44. }
  45. publicJasperPrintWithDataSource(){
  46. super();
  47. }
  48. publicJasperPrintWithDataSource(StringreportFilePath,Mapparams,JRDataSourcedataSource)
  49. throwsJasperReportException{
  50. if(reportFilePath==null||!reportFilePath.endsWith(".jasper"))
  51. thrownewJasperReportException("模板文件格式不对,请传入以.jasper为后缀的文件!");
  52. if(dataSource==null)
  53. thrownewJasperReportException("DataSource不应当为null!");
  54. this.setReportFilePath(reportFilePath);
  55. this.setParams(params);
  56. this.setDataSource(dataSource);
  57. }
  58. /**
  59. *取得JasperPrint
  60. *@return
  61. *@throwsJasperReportException
  62. */
  63. publicJasperPrintgetJasperPrint()throwsJasperReportException{
  64. FilereportFile=newFile(this.reportFilePath);
  65. if(!reportFile.exists())
  66. thrownewJasperReportException("传入的模板文件不存在!");
  67. try{
  68. //Load编译好的模板
  69. JasperReportjasperReport=(JasperReport)JRLoader.loadObject(reportFile.getPath());
  70. //进行数据填充
  71. JasperPrintjasperPrint=JasperFillManager.fillReport(jasperReport,this.params,this.dataSource);
  72. returnjasperPrint;
  73. }catch(JRExceptionjre){
  74. jre.printStackTrace();
  75. thrownewJasperReportException("在进行数据填充时发生了错误中,请检查是否是数据库连接错误或者是用来填充的参数map有误!");
  76. }
  77. }
  78. }
java 代码

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

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

java 代码
  1. /**
  2. *@copyRightBeijingTsing-TechReachwaySoftwareCo.,Ltd.
  3. *@authorJimmy.Shine2007-5-12
  4. */
  5. packagecn.com.reachway.framework.report.export;
  6. importjava.io.IOException;
  7. importjava.io.PrintWriter;
  8. importjava.sql.Connection;
  9. importjava.util.Map;
  10. importjavax.servlet.http.HttpServletRequest;
  11. importjavax.servlet.http.HttpServletResponse;
  12. importnet.sf.jasperreports.engine.JRDataSource;
  13. importnet.sf.jasperreports.engine.JRExporterParameter;
  14. importnet.sf.jasperreports.engine.JasperPrint;
  15. importnet.sf.jasperreports.engine.export.JRHtmlExporter;
  16. importnet.sf.jasperreports.engine.export.JRHtmlExporterParameter;
  17. importnet.sf.jasperreports.j2ee.servlets.ImageServlet;
  18. importcn.com.reachway.framework.exception.JasperReportException;
  19. importcn.com.reachway.framework.report.jasperPrint.JasperPrintWithConnection;
  20. importcn.com.reachway.framework.report.jasperPrint.JasperPrintWithDataSource;
  21. /**
  22. *利用报表生成HTML格式报表
  23. */
  24. publicclassHTMLExport{
  25. /**
  26. *导出报表
  27. *
  28. *@paramrequest
  29. *@paramresponse
  30. *@paramreportFilePath
  31. *@paramparams
  32. *@paramcon
  33. *@throwsJasperReportException
  34. */
  35. publicvoidexport(HttpServletRequestrequest,HttpServletResponseresponse,StringreportFilePath,Mapparams,
  36. Connectioncon)throwsJasperReportException{
  37. try{
  38. PrintWriterout=response.getWriter();
  39. try{
  40. response.setContentType("text/html;charset=UTF-8");
  41. JasperPrintjasperPrint=newJasperPrintWithConnection(reportFilePath,params,con).getJasperPrint();
  42. //使用JRHtmlExproter导出Html格式
  43. JRHtmlExporterexporter=newJRHtmlExporter();
  44. request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,jasperPrint);
  45. exporter.setParameter(JRExporterParameter.JASPER_PRINT,jasperPrint);
  46. exporter.setParameter(JRExporterParameter.OUTPUT_WRITER,out);
  47. exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI,"./servlets/image?image=");
  48. exporter.setParameter(JRExporterParameter.CHARACTER_ENCODING,"UTF-8");
  49. //导出
  50. exporter.exportReport();
  51. }catch(Exceptione){
  52. e.printStackTrace();
  53. thrownewJasperReportException("在导出Html格式报表时发生错误!");
  54. }finally{
  55. if(out!=null){
  56. try{
  57. out.close();
  58. }catch(Exceptione){
  59. }
  60. }
  61. }
  62. }catch(IOExceptionioe){
  63. ioe.printStackTrace();
  64. thrownewJasperReportException("")
  65. }
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics