使用jasperReport实现动态表头(转载)
2010-10-20 10:21
337 查看
最近在我公司drp(运营分销系统)开发中,需要大量报表,由于本人有过jasperReport的开发经验,所以选用了它,jr确实不错,开源,可扩展性很好,缺点就是免费的文档很少,更可气的是,代码中的doc少的可怜,基本上没有参考价值.
由于我们的产品是用于服装行业的,在服装行业有一个尺码组,非常的麻烦,在制作含有尺码组的报表时,表头的各种尺码不能写死,要从数据库查询出来.但是,一般的报表工具都是不支持表头动态化的(我理解,报表嘛,是呈现给特定人物如老板看的特定内容,表头应该是设计好的,不会经常性的更改),jasperReport也是一样,并不直接支持,细究它的实现过程,我们还是可以扩展从而解决这个问题的.
先看jasperReport的流程图.
从上图可看到,jrxml文件要通过JRXmlLoader解析为一个JasperDesign的对象,从源码中可以看出,此对象用java类去描述了报表的整个设计,比如,columnHeader,detail,columnFooter等等.然后由JasperCompileManager编译为一个JasperReport对象,其实,如果你用ireport(jasperReport报表的可视化设计器)制作报表,你完全可以不必理会怎样生成jaserReport对象.ireport对此有很好的支持.
了解了以上过程,我们可以看出,如果要动态的加入设计元素,只能在JasperDesign对象中下手.加入需要的动态元素,我的需求是在columnHeader中加入一个尺码组的表头,代码实现如下.
java 代码
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"要保持一致.
这个话题就到这儿了,我这儿还有一个我包装的工具类,我们公司的同事都认为对开发报表有帮助.
java 代码
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.
由于我们的产品是用于服装行业的,在服装行业有一个尺码组,非常的麻烦,在制作含有尺码组的报表时,表头的各种尺码不能写死,要从数据库查询出来.但是,一般的报表工具都是不支持表头动态化的(我理解,报表嘛,是呈现给特定人物如老板看的特定内容,表头应该是设计好的,不会经常性的更改),jasperReport也是一样,并不直接支持,细究它的实现过程,我们还是可以扩展从而解决这个问题的.
先看jasperReport的流程图.
从上图可看到,jrxml文件要通过JRXmlLoader解析为一个JasperDesign的对象,从源码中可以看出,此对象用java类去描述了报表的整个设计,比如,columnHeader,detail,columnFooter等等.然后由JasperCompileManager编译为一个JasperReport对象,其实,如果你用ireport(jasperReport报表的可视化设计器)制作报表,你完全可以不必理会怎样生成jaserReport对象.ireport对此有很好的支持.
了解了以上过程,我们可以看出,如果要动态的加入设计元素,只能在JasperDesign对象中下手.加入需要的动态元素,我的需求是在columnHeader中加入一个尺码组的表头,代码实现如下.
java 代码
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"要保持一致.
这个话题就到这儿了,我这儿还有一个我包装的工具类,我们公司的同事都认为对开发报表有帮助.
java 代码
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.
相关文章推荐
- Silverlight4中使用MEF实现页面的动态装配【转载】
- 转载 使用AJAX实现动态刷新页面功能
- 使用JavaScript动态设置样式实现代码及演示动画
- 使用ASP.NET Web API自带的类库实现对CORS的支持(在开发中使用这种方式)(转载)
- 使用FusionChart实现数据库的动态数据交互
- 使用反射和动态代理实现mybaits的mapping.xml热部署
- 使用Visifire+ArcGIS API for Silverlight实现Graphic信息的动态图表显示
- PHP使用方法重载实现动态创建属性的get和set方法
- 写MySQL存储过程实现动态执行SQL ——复制转载
- baseadapter.getItemId的使用方法:实现listview筛选、动态删除
- 分布式锁的几种实现方式~ 2016-11-07 分类:分布式 阅读(6870) 评论(4) 本站采用[知识共享署名-非商业性使用-相同方式共享 许可协议]进行许可,转载请在正文明显处注明原文地址
- JDK动态代理实现原理--转载
- 使用mvvmlight for win8 让GridViewItem项 实现动态命令导航
- 《EasyUI》——给DataGrid动态绑定表头和数据,实现表头与数据的真正解耦
- 使用Autolayout xib实现动态高度的TableViewCell
- 使用INDY的IdMappedPortTCP控件实现动态的HTTP代理服务器
- C#反射动态调用dll中的方法及使用QuartZ.net实现作业调度
- 使用LoaderManager管理Loader实现异步动态加载数据
- 使用Struts2实现文件的上传与动态下载(2)