使用jasperReport实现动态表头.docx

上传人:b****1 文档编号:573859 上传时间:2023-04-29 格式:DOCX 页数:13 大小:19.43KB
下载 相关 举报
使用jasperReport实现动态表头.docx_第1页
第1页 / 共13页
使用jasperReport实现动态表头.docx_第2页
第2页 / 共13页
使用jasperReport实现动态表头.docx_第3页
第3页 / 共13页
使用jasperReport实现动态表头.docx_第4页
第4页 / 共13页
使用jasperReport实现动态表头.docx_第5页
第5页 / 共13页
使用jasperReport实现动态表头.docx_第6页
第6页 / 共13页
使用jasperReport实现动态表头.docx_第7页
第7页 / 共13页
使用jasperReport实现动态表头.docx_第8页
第8页 / 共13页
使用jasperReport实现动态表头.docx_第9页
第9页 / 共13页
使用jasperReport实现动态表头.docx_第10页
第10页 / 共13页
使用jasperReport实现动态表头.docx_第11页
第11页 / 共13页
使用jasperReport实现动态表头.docx_第12页
第12页 / 共13页
使用jasperReport实现动态表头.docx_第13页
第13页 / 共13页
亲,该文档总共13页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

使用jasperReport实现动态表头.docx

《使用jasperReport实现动态表头.docx》由会员分享,可在线阅读,更多相关《使用jasperReport实现动态表头.docx(13页珍藏版)》请在冰点文库上搜索。

使用jasperReport实现动态表头.docx

使用jasperReport实现动态表头

使用jasperReport实现动态表头

最近在我公司drp(运营分销系统)开发中,需要大量报表,由于本人有过jasperReport的开发经验,所以选用了它,jr确实不错,开源,可扩展性很好,缺点就是免费的文档很少,更可气的是,代码中的doc少的可怜,基本上没有参考价值.

由于我们的产品是用于服装行业的,在服装行业有一个尺码组,非常的麻烦,在制作含有尺码组的报表时,表头的各种尺码不能写死,要从数据库查询出来.但是,一般的报表工具都是不支持表头动态化的(我理解,报表嘛,是呈现给特定人物如老板看的特定内容,表头应该是设计好的,不会经常性的更改),jasperReport也是一样,并不直接支持,细究它的实现过程,我们还是可以扩展从而解决这个问题的.

先看jasperReport的流程图.

从上图可看到,jrxml文件要通过JRXmlLoader解析为一个JasperDesign的对象,从源码中可以看出,此对象用java类去描述了报表的整个设计,比如,columnHeader,detail,columnFooter等等.然后由JasperCompileManager编译为一个JasperReport对象,其实,如果你用ireport(jasperReport报表的可视化设计器)制作报表,你完全可以不必理会怎样生成jaserReport对象.ireport对此有很好的支持.

了解了以上过程,我们可以看出,如果要动态的加入设计元素,只能在JasperDesign对象中下手.加入需要的动态元素,我的需求是在columnHeader中加入一个尺码组的表头,代码实现如下.

java代码packagemon.dynamicHeader;

importjava.io.File;

importjava.lang.reflect.InvocationTargetException;

importjava.util.Iterator;

importmons.beanutils.BeanUtils;

importnet.sf.jasperreports.engine.JRException;

importnet.sf.jasperreports.engine.JasperCompileManager;

importnet.sf.jasperreports.engine.JasperReport;

importnet.sf.jasperreports.engine.design.JRDesignBand;

importnet.sf.jasperreports.engine.design.JRDesignStaticText;

importnet.sf.jasperreports.engine.design.JasperDesign;

importnet.sf.jasperreports.engine.xml.JRXmlLoader;

/**

*@authoryaer

*/

@SuppressWarnings("unchecked")

publicclassReportDesignProcess{

privatestaticfinalStringflagTextKey="customFlagText";

publicstaticJasperReportgetJasperReport(StringxmlFilePath,

String[][]sizeGroup)throwsJRException{

JasperDesigndesign=getJasperDesign(xmlFilePath);

JRDesignBandcolumnHeader=(JRDesignBand)design.getColumnHeader();

reSetColumnHeaderHeight(columnHeader,sizeGroup);

reSetshapeAndPosition(columnHeader,sizeGroup);

addElementToColumnHeader(columnHeader,sizeGroup);

returnJasperCompileMpileReport(design);

}

privatestaticJasperDesigngetJasperDesign(StringfilePath)

throwsJRException{

returnJRXmlLoader.load(newFile(filePath));

}

privatestaticvoidreSetColumnHeaderHeight(JRDesignBandcolumnHeader,

String[][]sizeGroup){

columnHeader.setHeight(columnHeader.getHeight()*sizeGroup.length);

}

privatestaticJRDesignStaticTextgetFlagTextInDesign(

JRDesignBandcolumnHeader){

return(JRDesignStaticText)columnHeader.getElementByKey(flagTextKey);

}

privatestaticvoidreSetshapeAndPosition(JRDesignBandcolumnHeader,

String[][]sizeGroup){

JRDesignStaticTextflagText=getFlagTextInDesign(columnHeader);

Iterator<jrdesignstatictext></jrdesignstatictext>children=columnHeader.getChildren()

.iterator();

JRDesignStaticTextelement;

while(children.hasNext()){

element=children.next();

if(element.getX()>flagText.getX()){

element.setX(flagText.getX()+flagText.getWidth()

*sizeGroup[0].length);

}

if(!

flagTextKey.equals(element.getKey())){

element.setHeight(element.getHeight()*sizeGroup.length);

}

}

}

privatestaticvoidaddElementToColumnHeader(JRDesignBandcolumnHeader,

String[][]sizeGroup){

JRDesignStaticTextflagText=getFlagTextInDesign(columnHeader);

columnHeader.removeElement(flagText);

for(inti=0;i<sizeGroup.length;i++){

for(intj=0;j<sizeGroup[i].length;j++){

try{

JRDesignStaticTextnewElement=(JRDesignStaticText)BeanUtils

.cloneBean(flagText);

newElement.setText(sizeGroup[i][j]);

newElement.setX(flagText.getX()+flagText.getWidth()*j);

newElement.setY(flagText.getY()+flagText.getHeight()*i);

columnHeader.addElement(newElement);

}catch(IllegalAccessExceptione){

e.printStackTrace();

}catch(InstantiationExceptione){

e.printStackTrace();

}catch(InvocationTargetExceptione){

e.printStackTrace();

}catch(NoSuchMethodExceptione){

e.printStackTrace();

}

}

}

}

}

 

很遗憾,没有写注解,原因是我看了一本书叫<<测试驱动开发>>,里面有一句话"意图导向编程",意思是说,用手段比如容易理解,贴切的类名,方法名,属性达到让读者轻易理解代码.从而少写注解,让代码更简捷.如果大家不大明白以上代码的意思,那就是我写的不够好,还要继续努力.

  此类只有一个方法,根据传来的报表文件路径和一个二维数组式的尺码组生成一个jaserReport的对象.有三个关键方法.重新设置columnHeader的height;重新设置静态内容的形状和大小,添加新的元素到columnHeader中,其实,这儿有一个不太容易理的东西:

类中有一个flagTextKey的属性,它是标识报表设计中动态内容的一个样板元素,为什么要这个样板元素了,因为用它承载动态内容的样式,要比在用代码实现方便的多.请看BeanUtils.coloneBean()方法,实际上是克隆样板元素对象.

这个类设计的太具体于应用,应该写成一个抽象方法,让子类来具体实现加入动态元素的过程,我相信大家的需求和我不太一样.由于时间关系,我没有仔细考究.毕竟这只是一个参考实现.

  最后,在用于ireport画报表时就要注意了,一呈不变的元素该怎么画就怎么画,但样板元素的位置一定要放好.动态内容起始的位置和样式就靠它来定义,大多数时候,它是一个标签.只不过它的"key"属性和上面类的"flagTextKey"要保持一致.

  这个话题就到这儿了,我这儿还有一个我包装的工具类,我们公司的同事都认为对开发报表有帮助.

java代码packagemon;

importjava.util.ArrayList;

importjava.util.Collection;

importjava.util.HashMap;

importjava.util.Map;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpSession;

importjavax.faces.context.FacesContext;

importmons.lang.ArrayUtils;

importmon.dataSource.JRArrayCollectionDataSource;

importmon.dynamicHeader.ReportDesignProcess;

importnet.sf.jasperreports.engine.JRException;

importnet.sf.jasperreports.engine.JasperFillManager;

importnet.sf.jasperreports.engine.JasperPrint;

importnet.sf.jasperreports.engine.JasperReport;

importnet.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

importnet.sf.jasperreports.engine.JRDataSource;

importnet.sf.jasperreports.engine.util.JRLoader;

/**

*使用jasperReport做报表时的工具支持类.有两个用途,生成jasperPrint对象,和设置导出时的session

*

*@authoryaer

*@date2006-8-26

*@modifydate2006-12-8

*/

publicclassReportUtils{

publicstaticfinalStringXLS="xls";//导出为xls文件;

publicstaticfinalStringPDF="pdf";//导出为pdf文件;

privatestaticfinalStringJASPER="jasper";//编译过后的报表文件;

privatestaticfinalStringJRXML="jrxml";//原始的报表文件(xml格式);

privateHttpServletRequestrequest;

privateHttpSessionsession;

privateStringrootPath;//报表文件路径

/**

*在jsf环境下时构造些工具类对象

*

*@paramcontext

*jsf的上下文对象

*/

publicReportUtils(FacesContextcontext){

request=(HttpServletRequest)context.getExternalContext()

.getRequest();

session=(HttpSession)context.getExternalContext().getSession(true);

this.createRootPath(request);//生成报表文件的绝对路径

}

/**

*在其它web环境下构造此工具类对象

*

*@paramreq

*request请求对象

*/

publicReportUtils(HttpServletRequestreq){

this.request=req;

this.session=req.getSession();

this.createRootPath(request);//生成报表文件的绝对路径

}

/**

*获得报表文件的绝对路径

*

*@returnrootPath

*/

publicStringgetRootPath(){

returnrootPath;

}

/**

*获得JasperPrint对象;jasperPrint对象在jasperReport中是填充了报表数据后的一个实体,打印,导出,显示都要使用它.

*此方法含有java5.0支持的'可变参数'特性.params其实质是一个对象数组.在调用些方法时要注意它可能的参数顺序.

*此方法参数描述:

*1、最多只有四个参数。

*2、固定参数filePath表示报表文件的路径,为了支持drp系统中动态尺码组做表头的特性,filePath包括两类:

*编译过后的文件扩展名为'.jasper'和未编译的原始xml文件'.jrxml';

*若报表中有动态尺码组作表头,则filePath为扩展名是'.jrxml'的文件。

*若报表中不涉及动态尺码组,则filePath为扩展名是'.jasper'的文件。

*3、可变参数params的完整列表是(注意顺序):

Objectobj/CollectiondataSource,Stringseprator,String[][]sizeGroup.

*这三个参数中,有一个例外,Objectobj/CollectiondataSource必须有一个,此参数表示填充报表的数据,可以是一个Collection式的集合,

*也可以是一个model对象(有且只有一个Collection的属性);

*Stringseprator表示分隔符,如果数据源是一个Array的集合,则需此参数。

String[][]sizeGroup表款尺码组的二维数组。

*

*@paramfilePath

*@paramparams

*@returnjasperPrint

*/

publicJasperPrintgetJasperPrint(StringfilePath,Object...params){

JasperReportjasperReport=null;

try{

if(JASPER.equals(filePath.substring(filePath.indexOf(".")+1,

filePath.length()))){//jasper式文件的处理

jasperReport=getReportTemplate(filePath);

}

if(JRXML.equals(filePath.substring(filePath.indexOf(".")+1,

filePath.length()))){//jrxml式文件的处理

jasperReport=ReportDesignProcess.getJasperReport(filePath,

(String[][])params[params.length-1]);//重新设置表头,编译

params=ArrayUtils.remove(params,params.length-1);//删除参数中的sizeGroup

}

returnfillReport(jasperReport,params);

}catch(JRExceptione){

e.printStackTrace();

}

returnnull;

}

/**

*获得JasperPrint对象;自定义填充报表时的parameter和dataSource.参数说明和动态表头的用法参考上一方法

*@paramfilePath

*@paramparameter

*@paramdataSource

*@paramsizeGroup

*@return

*/

publicJasperPrintgetJasperPrint(StringfilePath,Mapparameter,

JRDataSourcedataSource,Object...sizeGroup){

JasperReportjasperReport=null;

try{

if(sizeGroup.length==0){

jasperReport=getReportTemplate(filePath);

}

if(sizeGroup.length==1){

jasperReport=ReportDesignProcess.getJasperReport(filePath,

(String[][])sizeGroup[sizeGroup.length-1]);//重新设置表头,编译

}

returnJasperFillManager.fillReport(jasperReport,parameter,

dataSource);

}catch(JRExceptione){

e.printStackTrace();

}

returnnull;

}

publicvoidsetAttrToPage(JasperPrintjasperPrint,Stringreport_fileName,

Stringreport_type){

session.setAttribute("REPORT_JASPERPRINT",jasperPrint);

session.setAttribute("REPORT_FILENAME",report_fileName);

session.setAttribute("REPORT_TYPE",report_type);

}

privateJasperPrintfillReport(JasperReportjasperReport,Object[]params)

throwsJRException{

Mapparameters=null;

JRDataSourceds=null;

if(params.length==0){

returnnull;

}

if(params.length==1&&params[0].getClass()==ArrayList.class){//其实质是要判断是否是集合

ds=newJRBeanCollectionDataSource((Collection)params[0]);

}

if(params.length==1&&params[0].getClass()!

=ArrayList.class){

ClassAnalysisca=newClassAnalysis(params[0]);

parameters=ca.getFields();

ds=newJRBeanCollectionDataSource(ca.getSet());

}

if(params.length==2&&params[0].getClass()==ArrayList.class){

ds=newJRArrayCollectionDataSource((Collection)

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2