




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、使用 jasperReport 实现动态表头最近在我公司 drp(运营分销系统 )开发中 ,需要大量报表 , 由于本人有过 jasperReport 的开发经验 ,所以选用了它 ,jr 确实不错 ,开源 ,可扩展性很好 ,缺点就是免费的文档很少 ,更可气的是 ,代码中的 doc 少的可怜 ,基本上没有参考价值 .由于我们的产品是用于服装行业的 ,在服装行业有一个尺码组 ,非常的麻烦 ,在制作含有尺码组的报表时 ,表头的各种尺码不能写死 ,要从数据库查询出来 .但是 ,一般的报表工具都是不支持表头动态化的 (我理解 ,报表嘛 ,是呈现给特定人物如老板看的特定内容 ,表头应该是设计好的 ,不会经常
2、性的更改),jasperReport 也是一样 ,并不直接支持 ,细究它的实现过程 ,我们还是可以扩展从而解决这个问题的.先看 jasperReport 的流程图 .从上图可看到,jrxml文件要通过JRXmlLoader解析为一个 JasperDesign 的对象 ,从源码中可以看出用 java 类去描述了报表的整个设计 ,比,此对象如,columnHeader,detail,columnFooter 等等 .然后由JasperCompileManager 编译为一个JasperReport 对象 ,其实 ,如果你用ireport(jasperReport报表的可视化设计器)制作报表,你完全
3、可以不必理会怎样生成jaserReport 对象 .ireport对此有很好的支持.了解了以上过程,我们可以看出 ,如果要动态的加入设计元素 ,只能在 JasperDesign 对象中下手 .加入需要的动态元素 ,我的需求是在columnHeader 中加入一个尺码组的表头,代码实现如下 .java 代码 packagemon.dynamicHeader;import java.io.File;import java.lang.reflect.InvocationTargetException; import java.util.Iterator;import mons.beanutils.B
4、eanUtils; import net.sf.jasperreports.engine.JRException;import net.sf.jasperreports.engine.JasperCompileManager; import net.sf.jasperreports.engine.JasperReport;import net.sf.jasperreports.engine.design.JRDesignBand; import net.sf.jasperreports.engine.design.JRDesignStaticText; import net.sf.jasper
5、reports.engine.design.JasperDesign; import net.sf.jasperreports.engine.xml.JRXmlLoader;/* author yaer*/SuppressWarnings(unchecked)public class ReportDesignProcess private static final String flagTextKey = customFlagText;public static JasperReport getJasperReport(String xmlFilePath,String sizeGroup)
6、throws JRException JasperDesign design = getJasperDesign(xmlFilePath);JRDesignBand columnHeader = (JRDesignBand)design.getColumnHeader();reSetColumnHeaderHeight(columnHeader,sizeGroup);reSetshapeAndPosition(columnHeader, sizeGroup);addElementToColumnHeader(columnHeader,sizeGroup);return JasperCompil
7、eMpileReport(design);private static JasperDesign getJasperDesign(String filePath)throws JRException return JRXmlLoader.load(new File(filePath);private static voidreSetColumnHeaderHeight(JRDesignBand columnHeader,String sizeGroup) columnHeader.setHeight(columnHeader.getHeight() *sizeGroup.length);pri
8、vate static JRDesignStaticText getFlagTextInDesign( JRDesignBand columnHeader) return (JRDesignStaticText)columnHeader.getElementByKey(flagTextKey);private static void reSetshapeAndPosition(JRDesignBand columnHeader,String sizeGroup) JRDesignStaticText flagText =getFlagTextInDesign(columnHeader);Ite
9、rator<jrdesignstatictext></jrdesignstatictext> children = columnHeader.getChildren().iterator();JRDesignStaticText element;while (children.hasNext() element = children.next();if (element.getX() > flagText.getX() element.setX(flagText.getX() +flagText.getWidth()* sizeGroup0.length);if
10、(!flagTextKey.equals(element.getKey() element.setHeight(element.getHeight() *sizeGroup.length);private static voidaddElementToColumnHeader(JRDesignBand columnHeader,String sizeGroup) JRDesignStaticText flagText =getFlagTextInDesign(columnHeader);columnHeader.removeElement(flagText); for (int i = 0;
11、i < sizeGroup.length; i+) for (int j = 0; j < sizeGroupi.length; j+) try JRDesignStaticText newElement = (JRDesignStaticText) BeanUtils.cloneBean(flagText);newElement.setText(sizeGroupij);newElement.setX(flagText.getX() +flagText.getWidth() * j);newElement.setY(flagText.getY() +flagText.getHei
12、ght() * i);columnHeader.addElement(newElement); catch (IllegalAccessException e) e.printStackTrace(); catch (InstantiationException e) e.printStackTrace(); catch (InvocationTargetException e) e.printStackTrace(); catch (NoSuchMethodException e) e.printStackTrace();很遗憾, 没有写注解, 原因是我看了一本书叫 << 测试驱
13、动开发 >>, 里面有一句话 意图导向编程 ,意思是说,用手段比如容易理解,贴切的类名,方法名,属性达到让读者轻易理解代码从而少写注解,让代码更简捷如果大家不大明白以上代码的意思,那就是我写的不够好,还要继续努力此类只有一个方法 ,根据传来的报表文件路径和一个二维数组式的尺码组生成一个 jaserReport 的对象 .有三个关键方法 .重新设置 columnHeader 的 height;重新设置静态内容的形状和大小 ,添加新的元素到 columnHeader 中 ,其实,这儿有一个不太容易理的东西:类中有一个 flagTextKey 的属性,它是标识报表设计中动态内容的一个样板
14、元素,为什么要这个样板元素了,因为用它承载动态内容的样式,要比在用代码实现方便的多 请看 BeanUtils.coloneBean() 方法 ,实际上是克隆样板元素对象这个类设计的太具体于应用,应该写成一个抽象方法,让子类来具体实现加入动态元素的过程,我相信大家的需求和我不太一样由于时间关系,我没有仔细考究毕竟这只是一个参考实现最后,在用于ireport 画报表时就要注意了,一呈不变的元素该怎么画就怎么画,但样板元素的位置一定要放好动态内容起始的位置和样式就靠它来定义,大多数时候,它是一个标签只不过它的key 属性和上面类的flagTextKey 要保持一致这个话题就到这儿了,我这儿还有一个我
15、包装的工具类,我们公司的同事都认为对开发报表有帮助java 代码 package mon;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import javax.faces.context.FacesContext;import mons.lang.ArrayUtils;imp
16、ortmon.dataSource.JRArrayCollectionDataSource;importmon.dynamicHeader.ReportDesignProcess;import net.sf.jasperreports.engine.JRException;import net.sf.jasperreports.engine.JasperFillManager;import net.sf.jasperreports.engine.JasperPrint;import net.sf.jasperreports.engine.JasperReport;importnet.sf.ja
17、sperreports.engine.data.JRBeanCollectionDataSource;import net.sf.jasperreports.engine.JRDataSource;import net.sf.jasperreports.engine.util.JRLoader;/* 使用jasperReport做报表时的工具支持类.有两个用途,生成 jasperPrint 对象 ,和设置导出时的 session* author yaer* date 2006-8-26* modify date 2006-12-8*/public class ReportUtils publi
18、c static final String XLS = xls;/导出为public static final String PDF = pdf;/导出为xls pdf文件 ;文件 ;private static final String JASPER = jasper;/编译过后的报表文件 ;private static final String JRXML = jrxml;/ 原始的报表文件 (xml 格式 );private HttpServletRequest request;private HttpSession session;private String rootPath;/报表
19、文件路径/* 在 jsf 环境下时构造些工具类对象* param context*jsf 的上下文对象*/public ReportUtils(FacesContext context) request = (HttpServletRequest)context.getExternalContext().getRequest();session = (HttpSession)context.getExternalContext().getSession(true); this.createRootPath(request);/ 生成报表文件的绝对路径/* 在其它 web 环境下构造此工具类对象
20、* param req*/request 请求对象public ReportUtils(HttpServletRequest req) this.request = req;this.session = req.getSession(); this.createRootPath(request);/ 生成报表文件的绝对路径/* 获得报表文件的绝对路径* return rootPath*/public String getRootPath() return rootPath;/* 获得 JasperPrint 对象 ; jasperPrint 对象在 jasperReport中是填充了报表数据后
21、的一个实体,打印 ,导出 ,显示都要使用它.* 此方法含有 java5.0 支持的 可变参数 特性 .params 其实质是一个对象数组 .在调用些方法时要注意它可能的参数顺序 .* 此方法参数描述 :* 1 、最多只有四个参数。* 2 、固定参数 filePath 表示报表文件的路径 ,为了支持drp 系统中动态尺码组做表头的特性, filePath 包括两类 :* 编译过后的文件扩展名为 .jasper和未编译的原始 xml 文件 .jrxml;*若报表中有动态尺码组作表头,则filePath 为扩展名是 .jrxml 的文件。* 若报表中不涉及动态尺码组 ,则 filePath 为扩展名
22、是.jasper的文件。* 3 、可变参数 params 的完整列表是 (注意顺序 ):Object obj/Collection dataSource,String seprator,String sizeGroup.* 这三个参数中 ,有一个例外 ,Object obj/CollectiondataSource 必须有一个,此参数表示填充报表的数据,可以是一个 Collection 式的集合 ,* 也可以是一个 model 对象 (有且只有一个Collection 的属性 );* String seprator 表示分隔符 ,如果数据源是一个Array 的集合 ,则需此参数。 String
23、sizeGroup表款尺码组的二维数组。* param filePath* param params* return jasperPrint*/public JasperPrint getJasperPrint(String filePath, Object.params) JasperReport jasperReport = null;try if(JASPER.equals(filePath.substring(filePath.indexOf(.) + 1,filePath.length() / jasper式文件的处理jasperReport = getReportTemplate(
24、filePath);if(JRXML.equals(filePath.substring(filePath.indexOf(.) + 1,filePath.length() / jrxml式文件的处理jasperReport =ReportDesignProcess.getJasperReport(filePath,(String) paramsparams.length- 1);/ 重新设置表头 ,编译params = ArrayUtils.remove(params,params.length - 1);/ 删除参数中的sizeGroupreturn fillReport(jasperRe
25、port, params); catch (JRException e) e.printStackTrace();return null;/* 获得 JasperPrint 对象 ;自定义填充报表时的parameter和 dataSource. 参数说明和动态表头的用法参考上一方法* param filePath* param parameter* param dataSource* param sizeGroup* return*/public JasperPrint getJasperPrint(String filePath, Map parameter,JRDataSource dat
26、aSource, Object. sizeGroup) JasperReport jasperReport = null; try if (sizeGroup.length = 0) jasperReport = getReportTemplate(filePath);if (sizeGroup.length = 1) jasperReport =ReportDesignProcess.getJasperReport(filePath,(String)sizeGroupsizeGroup.length - 1);/重新设置表头 ,编译return JasperFillManager.fillR
27、eport(jasperReport,parameter,dataSource); catch (JRException e) e.printStackTrace();return null;public void setAttrToPage(JasperPrint jasperPrint, String report_fileName,String report_type) session.setAttribute(REPORT_JASPERPRINT,jasperPrint);session.setAttribute(REPORT_FILENAME,report_fileName);ses
28、sion.setAttribute(REPORT_TYPE, report_type);private JasperPrint fillReport(JasperReport jasperReport, Object params)throws JRException Map parameters = null;JRDataSource ds = null;if (params.length = 0) return null;if (params.length = 1 && params0.getClass() = ArrayList.class) / 其实质是要判断是否是集合ds = newJRBeanCollectionDataSource(Collection) params0);if (params.length = 1 && para
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 湖南名校联考联合体2026届高三上学期第一次联考(暨入学检测)英语试题+答案
- 第二章-温热环境
- 2025生物科技公司精密仪器研发人员劳动雇佣合同样本
- 2025保定市顶级别墅租赁协议(含管家团队及绿化养护服务)
- 2025年新材料研发与应用推广中介服务合同范本
- 2025年城市老旧小区绿色节能改造项目施工承揽合同
- 2025年度生态养殖基地租赁协议范本(牛场绿色生态版)
- 2025年度综合型物流枢纽保安公司续签专项合同
- 国企考试题库及答案大全
- 2025年员工离职经济补偿与劳动仲裁风险防控服务合同
- 老年人口腔护理宣教
- 无人售货机的食品安全管理制度
- 鼻饲肠内营养腹泻的护理
- 高压氧舱培训
- 中餐分餐课件教学课件
- 检验科技术人员基本技能考核表2014
- 专题11读后续写海豚的秘密(二次开发微技能名校模拟)1月“九省联考”英语真题解读与考后变式训练
- 《教育心理学(第3版)》全套教学课件
- DL∕T 1917-2018 电力用户业扩报装技术规范
- 模态逻辑的本体论含义
- 中国舷外机(船外机)行业现状及趋势
评论
0/150
提交评论