Note For Me
the place I write down my taste of study
posts - 3,  comments - 13,  trackbacks - 0

在公司的项目中用JapserReport也做了不少报表了,现在也做个记录吧,很多东西都从网上而来,总结一下而已。

注意:本文由 bangke 所撰写 版权归属于bangke  转载请注明出处

1.下载不说了,需要JapserReport和iReport,要pdf支持中文的话需要itextasian.jar(google!)
2.资源:The JasperReports Ultimate Guide.pdf(google!)
 http://jasperreports.sourceforge.net/
 http://plateau.sicool.com (good!)
 源代码包下面的examples

3.先集中说一下中文支持问题:
   1)iReport中文显示:去掉iReport lib目录下的tinylaf.jar,会丑点儿:)
   2)要在pdf中显示中文:如下图设置字体或定义字体
      注意:在iReport中新建一个TextField会自动把pdf字体设为CP1252,需要修改,否则pdf输出会报错说找不到字体
font.gif

4.明确需求:
  JasperReport(0.5.2)目前支持Tabular形式的报表,分组,子报表
  不支持cross report(交叉表)和单元格合并。

5.JasperReport简述:
  JasperReport总的来说采用报表样式和数据相分离的设计,在报表杨始中定义好和数据源的映射关系,然后在实际应用的时候再用数据源填充样式得到最终的报表输出。
  1)数据源:
  在JasperReport中可以定义多种数据源,都实现了dori.jasper.engine.JRDataSource接口。
  接口有两个方法:
  public boolean next() throws JRException;
  public Object getFieldValue(JRField jrField) throws JRException;
  各个数据源简介:
  dori.jasper.engine.JRResultSetDataSource封装了一个java.sql.ResultSet
  dori.jasper.engine.JREmptyDataSource在没有实际数据源的数据的时候可以使用它
  dori.jasper.engine.data.JRTableModelDataSource封装了javax.swing.table.TableModel
  dori.jasper.engine.data.JRBeanArrayDataSource封装了an array of JavaBeans and uses reflection to retrieve report field values.
  dori.jasper.engine.data.JRBeanCollectionDataSource封装了java.util.Collection of JavaBeans,和上面的JRBeanArrayDataSource用法相像(强烈推荐,我一直都用它)
  简而言之就是JRDataSource中封装了一个循环的集合,在报表中一后会通过(属性名)反射来取得每个数据项的内容
  为什么选择JRBeanCollectionDataSource后面会解释。

  构造数据源,采用数据工厂(针对JRBeanCollectionDataSource来说),工厂方法:
 

public static JRDataSource getJRDataSource(String name,HttpServletRequest request) throws Exception{
    InterCustomerDS ds 
= null;//InterCustomerDS是一个interface!
    try {
      ds 
= (InterCustomerDS) Class.forName(name).
          newInstance();
      ds.createDS(request);
//这里需要request中的一些parameter来生成数据源
      return new JRBeanCollectionDataSource(ds.getBeanCollection());
    }

    
catch (ClassNotFoundException ex) {
      
throw new Exception(ex.getMessage());
    }

    
catch (IllegalAccessException ex) {
      
throw new Exception(ex.getMessage());
    }

    
catch (InstantiationException ex) {
      
throw new Exception(ex.getMessage());
    }


  }



  一个简单的数据源需要两个类,一个POJO,一个InterCustomerDS的实现

  POJO:

public class TestVO {
  
private String portfolio;
  
private String year;
  
private String period;

  
public CCSPVO() {
  }

  
public String getPeriod() {
    
return period;
  }

  
public String getPortfolio() {
    
return portfolio;
  }

  
public String getYear() {
    
return year;
  }

  
public void setPeriod(String period) {
    
this.period = period;
  }

  
public void setPortfolio(String portfolio) {
    
this.portfolio = portfolio;
  }

  
public void setYear(String year) {
    
this.year = year;
  }

 }

 

 TestDateSource:

public class TestDataSource implements InterCustomerDS {

  
private Collection co;
  
public CCSPDataSource() {
  }


  
public void createDS(HttpServletRequest request) throws Exception{
    co
=new ArrayList();
    
/*
    这之中做数据库查询,然后使用查询出来的结果生成TestVO,再把TestVO放入co中
    
*/

  }

  
  
public Object[] getBeanArray() {
    
return co.toArray();
  }


  
public Collection getBeanCollection() {
    
return co;
  }

}


 

  2)报表样式:
  JasperReport将一张报表分为了几个Sections,又叫bands(按照一张报表的内容来划分的):title, pageHeader, columnHeader, detail, columnFooter, pageFooter, summary, (如果有group的话,还有groupHeader和groupFooter)。用iReport画报表的工作简单得说就是把特定的内容放在特定的section中。
  title和summary在整个报表中只显示一次(不过有个选项可以设置为每页显示一次)
  column和page是每页显示一次
  detail才是最关键的地方,循环显示数据源的内容,直到全部显示完为止。
  在样式中的3个变量:fields,variables,parameters
  fields:从数据源传入样式的属性名(日后通过反射取值使用,所以fields名一定要和数据源中的属性名一样!比如使用JRBeanCollectionDataSource的话,fields名就要和javabean中对应的属性名一样!)
  parameters:应用程序向报表传入得非数据源形式的数据。
  variables:对fields,parameters,也包括所有java对象进行合法运算后得到的变量。(通常用做对数据源某个属性的统计,比如求和什么等等)
 
  具体使用iReport设计报表样式不说了,网上很多资料.
  需要注意的是
  在报表样式中可以输入表达式,也就是合法的java scriptlet
  在JasperReport中存在的都是java object所以某个textfield和对应数据的object类型一定要相同。
  parameters除了iReport默认的那些类型外其实可以使用任何java类型的。
  每个band在print when expression中输入返回Boolean的表达式可以控制是否显示
  可以使用group来添加bands,group其实并不需要和某个field对应,也就是说group没有expression是可以的,只不过又expression的话会按照expression(通常的fields)来动态分组(这里又需要注意,效果上和sql的group by相当,但并不需要在查询数据源的sql中写group by, JasperReport回自己帮你做好的)
  在输出数据的时候可以套用pattern,也就是正则表达式,比如输出Double的时候使用 #,##0.00 表示金额:1,234.00, #0.00表示1234.00
 
  3)输出报表
  采用一个Helper类,分别使用不同的方法得到填充了数据源的JasperPrint比如:
  

public JasperPrint getPrinterbyBeanCollection(File reportFile,Map reportParameters,JRBeanCollectionDataSource bean) throws Exception{
   
try {
     
if(!reportFile.exists()){
       
throw new Exception("the jasper file is not exist");
     }

     JasperReport jasperReport 
= (JasperReport) JRLoader.loadObject(reportFile.
         getPath());
     JasperPrint jasperPrint 
= JasperFillManager.fillReport(jasperReport,
         reportParameters, bean);
     
return jasperPrint;
   }

   
catch (JRException ex) {
     logger.error(
"report",ex);
     
throw new Exception(ex.getMessage());
   }

 }

  
  然后使用JasperPrint得到报表输出,比如html输出:
  

public void htmlExport(JasperPrint print,Map imagesMap,Object out) throws Exception{
    
try{
      JRHtmlExporter exporter 
= new JRHtmlExporter();
      exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
      exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, 
out);
      exporter.setParameter(JRHtmlExporterParameter.BETWEEN_PAGES_HTML, 
"");
      exporter.setParameter(JRHtmlExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
      exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, imagesMap);
      exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, 
"image?image=");
      exporter.exportReport();
    }
catch(Exception ex){
      logger.error(
"report",ex);
      
throw new Exception(ex.getMessage());
    }

  }

    
  
 

6.普通报表开发:
  开发3步骤
  1.定义POJO,写DataSource查询数据库生成一个Collection of POJOs
  2.使用iReport设计报表,定义和POJO属性一样的fields等
  3.用户输入web页面及输出的Servlet开发

7.SubReport
  其实和普通报表开发一样,只不过多写几个报表样式,POJO和DateSource。
  关键是在masterreport中对子报表的subreport选项卡中的Connection/DataSource Expression要选DataSource,然后填入你子报表的DataSource,当然先要把子报表的DataSource作为parameter传入masterreport。(这里JasperReport的example全是Connection的example,害的我想了半天,呵呵,实际上在J2EE这个要求解藕程度很高的范围内将sql写在报表样式中是不适合使用的)

8.最后说说为什么使用JRBeanCollectionDataSource,原因上面其实很多地方都说明了
  1。使用POJO和Collection简单,规范
  2。充分的解除报表样式和数据库之间的耦合,假如我要查询的sql变了,我只需要修改sql和结果集存入POJO的对应处,报表样式是不用修改的。

9.喝咖啡,休息,(其实我更喜欢喝雪碧,呵呵)!                                                                        

                                                                               本文由 bangke 所撰写 版权归属于bangke  转载请注明出处

posted on 2005-04-01 17:14 蚌壳 阅读(6805) 评论(11)  编辑  收藏 所属分类: Java In Work

FeedBack:
# re: JasperReport Notes
2005-06-09 17:27 | 有名氏
总结得非常好!!!  回复  更多评论
  
# re: JasperReport Notes
2005-07-21 11:35 | 无名氏
真TMD好!  回复  更多评论
  
# re: JasperReport Notes
2005-08-11 01:05 | 骆驼
接口InterCustomerDS不存在?  回复  更多评论
  
# re: JasperReport Notes
2005-08-11 01:07 | 骆驼
还有怎么向自定义数据源传递参数?谢谢  回复  更多评论
  
# re: JasperReport Notes
2005-09-14 09:27 | aron
子报表用JRBeanCollectionDataSource能不能给个例子
谢了
<a href="http://www.8qu.net/register.asp?net=aronzhou">谢谢</a>  回复  更多评论
  
# re: JasperReport Notes
2005-11-23 10:58 | 皮皮
怎么样才能让iReport中detail域中的内容不全显示出来,而是显示固定的页数,多余的内容不显示,少了的话不上空白该怎么实现呢?谢谢了:)

qq:239566375
邮箱:alice2331@163.com  回复  更多评论
  
# re: JasperReport Notes
2005-11-25 15:57 | shuli
用JasperReport做交叉报表,
纵向的值是可以变的
横向的值也是可以变的
这个JasperReport 怎么实现
高手指教,QQ:349283579 Email:to_liuchao@yahoo.com.cn  回复  更多评论
  
# ireport问题
2006-01-18 15:35 | 马上
急!!!怎么向自定义数据源传递参数?谢谢
  回复  更多评论
  
# re: JasperReport Notes
2006-03-09 13:52 | LIUXIAO
请教各位啦,有交叉报表的例子吗?我看了一些,可是不太明白,我是刚刚才开始研究Ireport+jasperreport,可以帮我一下吗?  回复  更多评论
  
# re: JasperReport Notes
2006-04-04 16:49 | kelo
是啊  回复  更多评论
  
# re: JasperReport Notes
2006-11-05 19:17 | tercel
能不能给个具体的例子放在这边下载,谢谢  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 

<2005年4月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿(4)

随笔分类(3)

随笔档案(3)

搜索

  •  

最新评论

阅读排行榜

评论排行榜