- 浏览: 396217 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
iris_1992:
2005年以前,国外开原报表完全碾压国产软件,但是现在国内软件 ...
JasperReport报表设计总结(一)(已完毕) -
水土第一:
在flash显示jasperprintlist的时候,根据下面 ...
JasperReport报表设计总结(三)(已完毕) -
水土第一:
结构分的很清晰。。。加上applet与jasper的东西就更完 ...
JasperReport报表设计总结(三)(已完毕) -
水土第一:
windowshead 写道import cn.com.rea ...
JasperReport报表设计总结(二)(已完毕) -
zwj1533:
下载的附件服务解压!
JasperReport报表设计总结(一)(已完毕)
以上文章转自http://yueho.iteye.com/blog/forum/3908
最近在我公司drp(运营分销系统)开发中,需要大量报表,由于本人有过jasperReport的开发经验,所以选用了它,jr确实不错,开源,可扩展性很好,缺点就是免费的文档很少,更可气的是,代码中的doc少的可怜,基本上没有参考价值.
由于我们的产品是用于服装行业的,在服装行业有一个尺码组,非常的麻烦,在制作含有尺码组的报表时,表头的各种尺码不能写死,要从数据库查询出来.但是,一般的报表工具都是不支持表头动态化的(我理解,报表嘛,是呈现给特定人物如老板看的特定内容,表头应该是设计好的,不会经常性的更改),jasperReport也是一样,并不直接支持,细究它的实现过程,我们还是可以扩展从而解决这个问题的.
先看jasperReport的流程图.
从上图可看到,jrxml文件要通过JRXmlLoader解析为一个JasperDesign的对象,从源码中可以看出,此对象用java类去描述了报表的整个设计,比如,columnHeader,detail,columnFooter等等.然后由JasperCompileManager编译为一个JasperReport对象,其实,如果你用ireport(jasperReport报表的可视化设计器)制作报表,你完全可以不必理会怎样生成jaserReport对象.ireport对此有很好的支持.
了解了以上过程,我们可以看出,如果要动态的加入设计元素,只能在JasperDesign对象中下手.加入需要的动态元素,我的需求是在columnHeader中加入一个尺码组的表头,代码实现如下.
- package com.webstone.drp.report.common.dynamicHeader;
- import java.io.File;
- import java.lang.reflect.InvocationTargetException;
- import java.util.Iterator;
- import org.apache.commons.beanutils.BeanUtils;
- 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.jasperreports.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) throws JRException {
- JasperDesign design = getJasperDesign(xmlFilePath);
- JRDesignBand columnHeader = (JRDesignBand) design.getColumnHeader();
- reSetColumnHeaderHeight(columnHeader, sizeGroup);
- reSetshapeAndPosition(columnHeader, sizeGroup);
- addElementToColumnHeader(columnHeader, sizeGroup);
- return JasperCompileManager.compileReport(design);
- }
- private static JasperDesign getJasperDesign(String filePath)
- throws JRException {
- return JRXmlLoader.load(new File(filePath));
- }
- private static void reSetColumnHeaderHeight(JRDesignBand columnHeader,
- String[][] sizeGroup) {
- columnHeader.setHeight(columnHeader.getHeight() * sizeGroup.length);
- }
- private static JRDesignStaticText getFlagTextInDesign(
- JRDesignBand columnHeader) {
- return (JRDesignStaticText) columnHeader.getElementByKey(flagTextKey);
- }
- private static void reSetshapeAndPosition(JRDesignBand columnHeader,
- String[][] sizeGroup) {
- JRDesignStaticText flagText = getFlagTextInDesign(columnHeader);
- Iterator<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()
- * sizeGroup[0].length);
- }
- if (!flagTextKey.equals(element.getKey())) {
- element.setHeight(element.getHeight() * sizeGroup.length);
- }
- }
- }
- private static void addElementToColumnHeader(JRDesignBand columnHeader,
- String[][] sizeGroup) {
- JRDesignStaticText flagText = getFlagTextInDesign(columnHeader);
- columnHeader.removeElement(flagText);
- for (int i = 0; i < sizeGroup.length; i++) {
- for (int j = 0; j < sizeGroup[i].length; j++) {
- try {
- JRDesignStaticText newElement = (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 (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
很遗憾,没有写注解,原因是我看了一本书叫<<测试驱动开发>>,里面有一句话"意图导向编程",意思是说,用手段比如容易理解,贴切的类名,方法名,属性达到让读者轻易理解代码.从而少写注解,让代码更简捷.如果大家不大明白以上代码的意思,那就是我写的不够好,还要继续努力.
此类只有一个方法,根据传来的报表文件路径和一个二维数组式的尺码组生成一个jaserReport的对象.有三个关键方法.重新设置columnHeader的height;重新设置静态内容的形状和大小,添加新的元素到columnHeader中,其实,这儿有一个不太容易理的东西:类中有一个flagTextKey的属性,它是标识报表设计中动态内容的一个样板元素,为什么要这个样板元素了,因为用它承载动态内容的样式,要比在用代码实现方便的多.请看BeanUtils.coloneBean()方法,实际上是克隆样板元素对象.
这个类设计的太具体于应用,应该写成一个抽象方法,让子类来具体实现加入动态元素的过程,我相信大家的需求和我不太一样.由于时间关系,我没有仔细考究.毕竟这只是一个参考实现.
最后,在用于ireport画报表时就要注意了,一呈不变的元素该怎么画就怎么画,但样板元素的位置一定要放好.动态内容起始的位置和样式就靠它来定义,大多数时候,它是一个标签.只不过它的"key"属性和上面类的"flagTextKey"要保持一致.
这个话题就到这儿了,我这儿还有一个我包装的工具类,我们公司的同事都认为对开发报表有帮助.
- package com.webstone.drp.report.common;
- 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 org.apache.commons.lang.ArrayUtils;
- import com.webstone.drp.report.common.dataSource.JRArrayCollectionDataSource;
- import com.webstone.drp.report.common.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;
- import net.sf.jasperreports.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 {
- public static final String XLS = "xls";// 导出为xls文件;
- public static final String PDF = "pdf";// 导出为pdf文件;
- private static final String JASPER = "jasper";// 编译过后的报表文件;
- private static final String JRXML = "jrxml";// 原始的报表文件(xml格式);
- private HttpServletRequest request;
- private HttpSession session;
- private String rootPath;// 报表文件路径
- /**
- * 在jsf环境下时构造些工具类对象
- *
- * @param context
- * jsf的上下文对象
- */
- public ReportUtils(FacesContext context) {
- request = (HttpServletRequest) context.getExternalContext()
- .getRequest();
- session = (HttpSession) context.getExternalContext().getSession(true);
- this.createRootPath(request);// 生成报表文件的绝对路径
- }
- /**
- * 在其它web环境下构造此工具类对象
- *
- * @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中是填充了报表数据后的一个实体,打印,导出,显示都要使用它.
- * 此方法含有java5.0支持的'可变参数'特性.params其实质是一个对象数组.在调用些方法时要注意它可能的参数顺序.
- * 此方法参数描述:
- * 1、最多只有四个参数。
- * 2、固定参数filePath表示报表文件的路径,为了支持drp系统中动态尺码组做表头的特性, filePath包括两类:
- * 编译过后的文件扩展名为'.jasper'和未编译的原始xml文件'.jrxml';
- * 若报表中有动态尺码组作表头,则filePath为扩展名是'.jrxml'的文件。
- * 若报表中不涉及动态尺码组,则filePath为扩展名是'.jasper'的文件。
- * 3、可变参数params的完整列表是(注意顺序):Object obj/Collection dataSource,String seprator,String[][] sizeGroup.
- * 这三个参数中,有一个例外,Object obj/Collection dataSource必须有一个,此参数表示填充报表的数据,可以是一个Collection式的集合,
- * 也可以是一个model对象(有且只有一个Collection的属性);
- * String seprator表示分隔符,如果数据源是一个Array的集合,则需此参数。String[][]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(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
- }
- return fillReport(jasperReport, 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 dataSource, Object... sizeGroup) {
- JasperReport jasperReport = null;
- try {
- if (sizeGroup.length == 0) {
- jasperReport = getReportTemplate(filePath);
- }
- if (sizeGroup.length == 1) {
- jasperReport = ReportDesignProcess.getJasperReport(filePath,
- (String[][]) sizeGroup[sizeGroup.length - 1]);// 重新设置表头,编译
- }
- return JasperFillManager.fillReport(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);
- session.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 && params[0].getClass() == ArrayList.class) {//其实质是要判断是否是集合
- ds = new JRBeanCollectionDataSource((Collection) params[0]);
- }
- if (params.length == 1 && params[0].getClass() != ArrayList.class) {
- ClassAnalysis ca = new ClassAnalysis(params[0]);
- parameters = ca.getFields();
- ds = new JRBeanCollectionDataSource(ca.getSet());
- }
- if (params.length == 2 && params[0].getClass() == ArrayList.class) {
- ds = new JRArrayCollectionDataSource((Collection) params[0],
- params[1].toString());
- }
- if (params.length == 2 && params[0].getClass() != ArrayList.class) {
- ClassAnalysis ca = new ClassAnalysis(params[0]);
- parameters = ca.getFields();
- ds = new JRArrayCollectionDataSource(ca.getSet(), params[1]
- .toString());
- }
- return JasperFillManager.fillReport(jasperReport,
- parameters == null ? new HashMap() : parameters, ds);
- }
- private void createRootPath(HttpServletRequest request) {
- rootPath = request.getSession().getServletContext().getRealPath("/")
- + "WEB-INF\\classes\\com\\webstone\\drp\\report\\jaser\\";
- }
- private JasperReport getReportTemplate(String jasperPath)
- throws JRException {
- return (JasperReport) JRLoader.loadObject(rootPath + jasperPath);
- }
- }
此类用于生成填充后报表对象jasperPrint.
发表评论
-
谨慎使用IDEA12的并行编译模式
2012-12-14 11:07 1232IDEA 12 提供了使用扩展工具进行并行编译的功能,但是请谨 ... -
JavaMail使用注意
2012-12-12 23:55 1023在使用JavaMail发送邮件时候,需要注意,如果在收件人中过 ... -
Take care of JPA MERGE
2012-12-12 23:52 1153在使用JPA的MERGE的时候要注意: 1、将多执行一次SE ... -
Tomcat SSL正确配置
2010-12-08 14:36 1491<Connector protocol=&quo ... -
jFreechart三种图的测试代码
2010-05-10 11:17 1886Jfreechart的最新版本,对 ... -
近期看的书
2010-03-18 21:25 1220SONY PRS600。技术类的电子书一本一本的看,记录一下: ... -
开源的宿命
2009-08-11 21:06 1230Vmware收购了Spring,这绝对是一个令人震惊的消息,我 ... -
Java生成文件时的编码的问题
2009-01-05 08:40 9670最近在做RCP应用的时候,需要生成文件,而使用编码为UTF-8 ... -
Java EE架构调查
2008-11-04 21:23 1303近期准备升级技术框架。 准备升级为: JSF + Seam + ... -
框架升级兼新书推荐
2008-10-17 09:23 1396终于可以静下心来,做框架的研发了。经过无数次的努力,将项目做到 ... -
InstallAnywhere
2008-07-21 11:25 1597随着开发系统的加大,对 ... -
Portlet
2008-07-12 20:35 1617Portlet技术已经被广泛运用,转载此文目的在于大家一窥Po ... -
以SSL加强Tomcat的安全防护能力
2008-07-11 01:55 1421关于如何在TOMCAT中使用SSL的文档。 由于插入图片太 ... -
越来越无知了
2008-07-08 22:22 1380学习知识总有一个过程,大体上是这样。 感觉自己什么都不知道-- ... -
netBeans6.1与eclipse
2008-05-24 00:42 1781为了学习JavaFX,遵照于官方教程,下载了netBeans, ... -
详细讲解Java中log4j的使用方法
2008-01-07 16:37 16671、Log4j是什么? Log4j可以帮助调试(有时候de ... -
以不合适的方式在编程
2007-12-12 20:49 1170越来越喜欢组件化的开发了,可能是对于组件化开发的喜欢。 在Ja ... -
Log4j的使用以及在Spring中集成(转)
2007-12-09 09:27 4701log4j简介 简单的说log4j ... -
JBoss Tools--eclipse开发基于B/S模式下的必备插件
2007-11-27 13:32 4191JBoss是越来越强大了,一直有使用JBoss的,自从归属于R ... -
eclipse3.4到底改变了什么,陈桥五笔无法使用
2007-11-26 09:57 1948Eclipse发布了3.4M3,内置了许多有用的新功能,最直接 ...
相关推荐
在本文中,我们将深入探讨如何使用JasperReport来实现动态表头,这是一个在报表生成过程中非常重要的特性,尤其是在处理如服装行业中需要灵活调整的尺码组数据时。JasperReport是一个开源的报表工具,具有良好的可...
在本文中,我们将深入探讨如何使用JasperReport实现动态表头,特别是针对尺码组这样的特殊需求。 1. **JasperReport流程**: JasperReport的工作流程包括XML解析、设计对象构建和编译。首先,JRXML文件被`...
4. **使用变量和计算**:为了实现表头的折叠和展开,可以利用变量跟踪当前的组级别,并根据需要显示或隐藏相应的表头。此外,还可以使用计算字段来动态计算某些汇总值,如总和、平均值等。 5. **运行时动态生成**:...
在JasperReport中,我们可以使用“组”(Group)功能来实现动态表头。每个组都有自己的表头,当数据变化时,相应的表头会自动显示。例如,对于一个销售报表,可以按照地区、年份、季度等进行分组,每个级别的分组都...
同时,合理地使用动态表头和按组分页可以提供更好的用户体验,帮助用户快速理解和解析大量数据。 6. **实战应用**: 在实际项目中,这样的报表设计方法适用于大型企业报表系统,尤其是那些需要处理大量分类数据,...
总的来说,这个项目展示了如何在不使用`subreport`的情况下,利用JasperReport的动态表头和分组功能来创建一个高效、灵活的报表解决方案。对于那些需要处理大量数据和复杂结构的Java应用来说,这样的优化是至关重要...
在这个特定的案例中,我们关注的是如何在JasperReport和iReport中实现固定表头以及隐藏和显示列的功能。 首先,让我们了解一下JasperReport。JasperReport是一个开源的报表库,它允许开发者在各种应用程序中生成...
这个特定的压缩包文件包含了一个关于如何实现jasperreport动态列以及生成HTML导出的示例,对于使用Eclipse进行Java开发的人员来说,这是一个非常实用的学习资源。 动态列的概念在于,报表的列数不是固定的,而是...
jasperReport使用Java语言开发,可以与多种开发平台集成。 在实现动态列打印时,我们需要首先从页面中获取要查询的字段,然后根据选择的字段生成相应的报表。下面是实现代码的部分内容: ```java String[] print...
4. **使用`group`**:jasperReport的分组功能也可以帮助实现动态合并。通过设置分组,可以在每个分组的开头和结尾自动插入新行,当数据在同一分组内时,可以利用`printWhenGroupChanges`属性来决定是否合并。 5. **...
实现了jasperReport进行报表动态列的实现,使用者只需要利用eclipse将工程文件导入,即可查看运行结果的展示,不需要其他的配置和jar包如果想进行动态展示只需要修改构造参数就可以看到动态的展示
本主题将深入探讨如何利用JasperReport实现动态单元格合并,支持多层分组排序和多分组动态合并单元格。 首先,我们要理解JasperReport的基本概念。JasperReport是一个基于Java的报告设计库,它允许开发者通过JRXML...
NULL 博文链接:https://bighappy1983.iteye.com/blog/1850827
在“JasperReport动态报表归并行数据”这个主题中,我们主要讨论如何利用JasperReport来处理和展示动态变化的数据,并实现数据的合并。 1. **动态报表设计**: JasperReport支持XML或Java代码定义报表模板(jrxml...
**JasperReport动态生成报表** JasperReport是一款强大的开源报表工具,主要用于生成各种复杂的静态和动态报表。它基于Java,可以很好地与Java应用程序、Web应用和企业级应用集成,提供丰富的报表设计和灵活的数据...
使用jasperReport实现动态表头.doc详细介绍了如何利用API创建可变的、层次化的表头,这对于处理复杂的数据结构非常有用。 1. JasperReport API:学习如何创建和填充jasperReport模板,理解JRDesign对象和...
标题“使用JasperReport输出image图像”涉及到的关键技术点是JasperReport的图像生成和导出功能。在描述中提到的场景是,一个项目需要在文档中添加可识别的元素,比如条形码,然后将包含这些元素的文档作为图像保存...
总的来说,SpringBoot与JasperReport的整合使得报表生成变得简单,它提供了灵活的设计工具和丰富的数据绑定能力,可以帮助开发者快速地实现复杂报表的展示需求。通过学习和掌握这一技术,你可以提升企业应用的报表...
在IT行业中,报表生成是许多应用的核心功能,而JasperReport是Java环境下广泛使用的开源报表工具,它允许开发者创建复杂的报告并以多种格式输出,如PDF、HTML、Excel等。本篇文章将详细讲解如何利用JasperReport制作...
标题中的“jasperreport生成pdf实现下载与打印”是指使用JasperReports库来创建PDF报告,并提供下载和打印功能。JasperReports是一个开源的Java报表工具,它允许开发者设计、生成和导出各种类型的报表,包括PDF、...