- 浏览: 1748017 次
- 性别:
- 来自: 大连
博客专栏
-
Spring数据库访问系列...
浏览量:172816
-
Android学习笔记
浏览量:366549
-
iBatis开发详解
浏览量:188303
-
Objective-C学习...
浏览量:98739
最新评论
-
iLidy:
引用[/c
Hibernate持久化对象的生命周期详解 -
fengzigogo:
您好,有这个项目架构的源码下载地址吗?
一种Java Web应用开发框架的构建(基于Struts2+Spring+FreeMarker)之一 -
spring_springmvc:
可以参考最新的文档:如何在eclipse jee中检出项目并转 ...
用Maven构建Java Web开发环境(Jetty容器)之二 -
springdata_springmvc:
spring mvc demo教程源代码下载,地址:http: ...
Spring 3之MVC & Security简单整合开发(二) -
赵庆辉:
看帖回复是美德,楼主讲的很清晰明了,看了豁然开朗.
Java String对象的经典问题(new String())
本文接http://sarin.iteye.com/blog/658145继续研究。
之前我们用JasperReport制作报表使用的是JDBC数据源。当使用JDBC作为数据源时,JasperReport在运行时会检测数据库是否可用,也就是说它会自己连接一下数据库。而我们要使用远程方法时,数据库不在本地,那么我们就不能使用JDBC数据源了,因为JasperReport在不可访问数据源时会抛异常。此时,我们就必须使用JavaBean作为数据源了。比如通过WebService/RMI方式获取数据的话,就要走JavaBean数据源的方式了。
先定义一个功能需求,然后我们展开说明。一个车辆行驶数据分析系统中需要实时获取行驶数据,这需要车载设备来实现。数据上传存储在Web端的数据库中,我们需要从数据库中获取数据来显示内容。
使用JavaBean作为数据源,首先我们要扩展JasperReport的数据源。实现方法很简单,我们定义一个类去实现net.sf.jasperreports.engine.JRDataSource接口即可,覆盖其中的方法。下面给出一个示例。
因为扩展的数据源中使用了VO值对象,这里给出这个值对象。使用VO的好处就是从数据库读取的结果集直接封装成自定义的VO类型,放在List中也是泛型的一种实现,非常方便使用。
数据源我们都配置好了,剩下的就是往JasperReport模板文件中填充了,而模板文件的设计是和普通JDBC数据源不同的,这里我们来详细说明一下。iReport工具我们使用3.7.2版本的,同时项目类库中JasperReport的版本也要和iReport工具一致,否则是不能编译的。
打开iReport,点击工具中的选项,找到classpath选项卡,增加我们的项目的类路径,这样我们就能在iReport中使用我们设定好的VO对象了。如下图所示:
设置好classpath后,我们开始设计报表模板,首先要设置数据源,我们选择JavaBean数据源,这里的Class Name要输入类的全名(含包名),然后点击Read attributes就可以读取到类中的属性了,我们选择全部添加进来,如下图所示:
我们得到如下的设计模板。
这里我们说几个注意的地方。日期字段可能是多条相同的记录,那么相同的日期只显示一次,在模板中我们需要多设置一下,就是把属性中的Print Report Value选项去掉,那么为了显示的好看,我们还需要特殊设置一下Padding and Borders,下边界不能显示。如下图所示:
而问题还没有全部解决,因为重复不显示的那部分边界就也不显示了,所以还需要特殊处理重复不显示那部分格子的边界。我们添加一个静态文本块static field,设置和日期字段完全重合。如下图所示:
还要说明的是数据超长问题的处理,正如这个模板中的起始地点和结束地点,因为显示的数据过多而留给他们的空间有限,如果这两个字段的数据过长,那么显示就会出现问题,这是必须要处理的问题。这个处理也很简单,我们选中需要超长处理的字段,然后在属性面板中勾选Stretch With Overflow选项,这时如果数据超长就会自动换行了。
而问题又出现了,如果这两个字段自动换行了,那么必然把一行上的其他元素都给撑大了,那么还需要对其他元素进行设置。选中其他的所有元素,在属性面板的Stretch Type中选择Relative to Tallest Object就可以自适应到最高换行的元素了,显示效果就正常了。
若报表在页面显示时,也要考虑日期合并的问题,那么就需要在流程中进行处理了。而页面中的合并涉及到rowspan的数值和td中的参数,这是需要处理的地方。这里很自然想到设计一个VO来匹配页面。那么我们设计ColsVO来实现,代码如下:
下面就是对取出的数据集合进行处理了,我们先来说明页面显示的代码的处理算法。
这样我们对原来的数据集合dataList进行遍历处理,就得到了处理后的集合returnList,在页面用FreeMarker进行遍历显示,代码如下:
这样就可以显示合并的效果了,我们看一下效果图片
日期字段就已经合并显示了,而直接遍历List是不能做到的,而合并算法可能存在问题,希望和大家交流。
剩下就是报表的打印了。看一下报表打印的核心代码。
其余部分就和正常是一样的了,只是数据源的设置上使用我们扩展的JRDataSource就行了。我们看看打印出来的PDF效果。
字段已经合并了,但是合并字段的居中还是个问题,需要继续研究。
前面说过使用JavaBean作为数据源是因为Web应用中数据是远程方法调用过来的,而不是在本地数据库生成的。下面用RMI方法来说明本例中的数据获取设置。当然WebService的实现还有很多。
在Spring的配置文件中,要注入属性,代码如下:
我们在Action代码中就可以通过RMI的接口获取远端的数据了。代码如下:
这样就可以通过RMI获取到远端的实现数据了,远端的实现这里就不列出了。
一家之言,仅供参考,希望对使用者有用,欢迎交流。
之前我们用JasperReport制作报表使用的是JDBC数据源。当使用JDBC作为数据源时,JasperReport在运行时会检测数据库是否可用,也就是说它会自己连接一下数据库。而我们要使用远程方法时,数据库不在本地,那么我们就不能使用JDBC数据源了,因为JasperReport在不可访问数据源时会抛异常。此时,我们就必须使用JavaBean作为数据源了。比如通过WebService/RMI方式获取数据的话,就要走JavaBean数据源的方式了。
先定义一个功能需求,然后我们展开说明。一个车辆行驶数据分析系统中需要实时获取行驶数据,这需要车载设备来实现。数据上传存储在Web端的数据库中,我们需要从数据库中获取数据来显示内容。
使用JavaBean作为数据源,首先我们要扩展JasperReport的数据源。实现方法很简单,我们定义一个类去实现net.sf.jasperreports.engine.JRDataSource接口即可,覆盖其中的方法。下面给出一个示例。
package xxx.xxx.web.bean; import java.util.List; import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRField; public class DrivingHistoryDataSource implements JRDataSource { //数据集合,使用到了一个VO值对象 private List<DrivingHistoryDataVO> list; private int i = -1; //构造方法,初始化list public DrivingHistoryDataSource(List<DrivingHistoryDataVO> list) { super(); this.list = list; } //覆盖接口中的方法,给List添加参数 public Object getFieldValue(JRField jrField) throws JRException { Object value = null; String fieldName = jrField.getName(); if ("id".equals(fieldName)) { value = list.get(i).getId(); } else if (){ //剩余参数的填充这里就省略了,Java 7中的Switch可以使用字符串了就不用这样else if重复写了。 } return value; } //覆盖接口中的next()方法 public boolean next() throws JRException { i++; if (list == null) { return false; } return (i < list.size()); } }
因为扩展的数据源中使用了VO值对象,这里给出这个值对象。使用VO的好处就是从数据库读取的结果集直接封装成自定义的VO类型,放在List中也是泛型的一种实现,非常方便使用。
package xxx.xxx.web.bean; import java.io.Serializable; public class DrivingHistoryDataVO implements Serializable{ private int id;//主键 //其余的属性省略了 //默认的构造方法 public DrivingHistoryDataVO() { super(); } //带参数的构造方法,省略其余参数 public DrivingHistoryDataVO(int id) { super(); this.id = id; } public int getId() { return id; } public void setId(int id) { this.id = id; } //其余的getter和setter方法省略了 }
数据源我们都配置好了,剩下的就是往JasperReport模板文件中填充了,而模板文件的设计是和普通JDBC数据源不同的,这里我们来详细说明一下。iReport工具我们使用3.7.2版本的,同时项目类库中JasperReport的版本也要和iReport工具一致,否则是不能编译的。
打开iReport,点击工具中的选项,找到classpath选项卡,增加我们的项目的类路径,这样我们就能在iReport中使用我们设定好的VO对象了。如下图所示:
设置好classpath后,我们开始设计报表模板,首先要设置数据源,我们选择JavaBean数据源,这里的Class Name要输入类的全名(含包名),然后点击Read attributes就可以读取到类中的属性了,我们选择全部添加进来,如下图所示:
我们得到如下的设计模板。
这里我们说几个注意的地方。日期字段可能是多条相同的记录,那么相同的日期只显示一次,在模板中我们需要多设置一下,就是把属性中的Print Report Value选项去掉,那么为了显示的好看,我们还需要特殊设置一下Padding and Borders,下边界不能显示。如下图所示:
而问题还没有全部解决,因为重复不显示的那部分边界就也不显示了,所以还需要特殊处理重复不显示那部分格子的边界。我们添加一个静态文本块static field,设置和日期字段完全重合。如下图所示:
还要说明的是数据超长问题的处理,正如这个模板中的起始地点和结束地点,因为显示的数据过多而留给他们的空间有限,如果这两个字段的数据过长,那么显示就会出现问题,这是必须要处理的问题。这个处理也很简单,我们选中需要超长处理的字段,然后在属性面板中勾选Stretch With Overflow选项,这时如果数据超长就会自动换行了。
而问题又出现了,如果这两个字段自动换行了,那么必然把一行上的其他元素都给撑大了,那么还需要对其他元素进行设置。选中其他的所有元素,在属性面板的Stretch Type中选择Relative to Tallest Object就可以自适应到最高换行的元素了,显示效果就正常了。
若报表在页面显示时,也要考虑日期合并的问题,那么就需要在流程中进行处理了。而页面中的合并涉及到rowspan的数值和td中的参数,这是需要处理的地方。这里很自然想到设计一个VO来匹配页面。那么我们设计ColsVO来实现,代码如下:
package xxx.xxx.web.bean; /** * 统计报表用VO,代表一个单元格 */ public class ColsVO { private String value;//单元格显示的值 private int rowspan;//单元格占几行 public ColsVO() { super(); } public ColsVO(String value, int rowspan) { super(); this.value = value; this.rowspan = rowspan; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public int getRowspan() { return rowspan; } public void setRowspan(int rowspan) { this.rowspan = rowspan; } }
下面就是对取出的数据集合进行处理了,我们先来说明页面显示的代码的处理算法。
public List<Map> getResultList(List<DrivingHistoryDataVO> dataList) { List<Map> returnList = new ArrayList<Map>(); // 保证记录顺序不变,使用TreeMap Map<String, Object> tempMap = null; // 日期合并记录数 int dateRowspan = 0; for (int i = 0; i < dataList.size(); i++) { tempMap = new HashMap<String, Object>(); DrivingHistoryDataVO rawVO = dataList.get(i); // 先填充不需要合并的字段 returnList.add(tempMap); // 需要合并日期,单独处理 // 是否是最后一条记录的开关 boolean last = (i == dataList.size() - 1); // 取出两条记录进行比较 DrivingHistoryDataVO hdVo1 = null; DrivingHistoryDataVO hdVo2 = null; if (!last) { hdVo1 = dataList.get(i); hdVo2 = dataList.get(i + 1); } else { // 防止最后一条记录无法加入集合 hdVo1 = dataList.get(i); if (dataList.size() != 1) hdVo2 = dataList.get(i - 1); else hdVo2 = dataList.get(i); } String date1 = hdVo1.getDate(); String date2 = hdVo2.getDate(); // 比较date1和date2,如果相同,计数器加1;不同,更新统一日期的第一条记录,计数器清零 if (date1.equals(date2)) { if (dataList.size() == 1) { ColsVO colsVO = new ColsVO(hdVo1.getDate(), 1); returnList.get(0).put("colsVO", colsVO); } else if (last) { ColsVO colsVO = new ColsVO(hdVo1.getDate(), dateRowspan + 1); returnList.get(i - dateRowspan).put("colsVO", colsVO); } else { dateRowspan++; } } else { ColsVO colsVO = new ColsVO(hdVo1.getDate(), dateRowspan + 1); returnList.get(i - dateRowspan).put("colsVO", colsVO); dateRowspan = 0; } } return returnList; }
这样我们对原来的数据集合dataList进行遍历处理,就得到了处理后的集合returnList,在页面用FreeMarker进行遍历显示,代码如下:
<#list returnList as info> <tr> <#if info.colsVO?has_content> <td rowspan="${ info.colsVO.rowspan}">${ info.colsVO.value}</td> <#else> </#if> <td>${info.XXX}</td> <td>${info.XXX}</td> </tr> </#list>
这样就可以显示合并的效果了,我们看一下效果图片
日期字段就已经合并显示了,而直接遍历List是不能做到的,而合并算法可能存在问题,希望和大家交流。
剩下就是报表的打印了。看一下报表打印的核心代码。
String jrxmlPath = this.getClass().getClassLoader().getResource("/xxx.xxx.template").getPath()+"/report.jrxml"; JasperReport report = JasperCompileManager.compileReport(jrxmlPath); JasperPrint jasperPrint = JasperFillManager.fillReport(report, null, new DrivingHistoryDataSource(dataList));
其余部分就和正常是一样的了,只是数据源的设置上使用我们扩展的JRDataSource就行了。我们看看打印出来的PDF效果。
字段已经合并了,但是合并字段的居中还是个问题,需要继续研究。
前面说过使用JavaBean作为数据源是因为Web应用中数据是远程方法调用过来的,而不是在本地数据库生成的。下面用RMI方法来说明本例中的数据获取设置。当然WebService的实现还有很多。
package xxx.xxx.service; import org.springframework.remoting.rmi.RmiProxyFactoryBean; /** * 获取RMI远程访问接口 */ public class WebServiceClientService{ private String serviceName;//WebService服务名 private String registryPort;//WebService注册端口号 public void setServiceName(String serviceName) { this.serviceName = serviceName; } public void setRegistryPort(String registryPort) { this.registryPort = registryPort; } /** * 获取RMI接口 * @param ip * @return */ private RmiProxyFactoryBean getRmiProxyFactoryBean(String ip){ RmiProxyFactoryBean rpf=new RmiProxyFactoryBean(); StringBuffer url=new StringBuffer(); url.append("rmi://"); url.append(ip); url.append(":"); url.append(registryPort); url.append("/"); url.append(serviceName); rpf.setServiceUrl(url.toString()); return rpf; } /** * 设置RMI远程访问接口生效 */ private void setRmiProxyFactoryBean(RmiProxyFactoryBean rpf){ rpf.afterPropertiesSet(); } /** * 获取RMI车辆数据接口 */ public DrivingHistoryDataWebService getDrivingHistoryDataWebService(String ip){ RmiProxyFactoryBean rpf=this.getRmiProxyFactoryBean(ip); rpf.setServiceInterface(DrivingHistoryDataWebServiceIF.class); this.setRmiProxyFactoryBean(rpf); return (DrivingHistoryDataWebService)rpf.getObject(); } }
在Spring的配置文件中,要注入属性,代码如下:
<bean id="drivingHistoryDataClientService" class="xxx.xxx.service.WebServiceClientService"> <property name="serviceName" value="DrivingHistoryDataWebService"/> <property name="registryPort" value="1234"/> </bean>
我们在Action代码中就可以通过RMI的接口获取远端的数据了。代码如下:
DrivingHistoryDataWebService hdws = getWebServiceClientService().getDrivingHistoryDataWebService(ip); List<DrivingHistoryDataVO> dataList = hdws.getDrivingHistoryDataList(new Object[]{xxx,xxx,xxx});
这样就可以通过RMI获取到远端的实现数据了,远端的实现这里就不列出了。
一家之言,仅供参考,希望对使用者有用,欢迎交流。
发表评论
-
HTML5/CSS3翻转动画(二)
2011-12-31 11:28 9517上一篇我们制作了两行文字的翻转效果,他们是同步进行的, ... -
HTML5/CSS3翻转动画(一)
2011-12-30 13:43 17600翻转动画效果,就是将页面的元素(文字,图片)加入围绕坐 ... -
HTML5/CSS3清爽后台番外篇-添加锁屏效果
2011-10-29 12:34 10214锁屏效果,也就是将屏幕置于模态,不允许用户触发任何动作 ... -
基于HTML5/CSS3的清爽后台管理页面(二)
2011-10-02 09:11 12936本文接上一篇继续来介绍企业级开发中后台管理页面的制作。 ... -
基于HTML5/CSS3的清爽后台管理页面(一)
2011-10-01 21:36 20441后台管理系统是企业级开发中必不可少的组成部分,一般来说 ... -
HTML5绘制饼图实例(二)
2011-08-15 21:16 11142本文接上一讲继续 ... -
HTML5绘制饼图实例(二)
2011-08-15 20:48 8本文接上一讲继续来说明 我们继续来制作饼图示例 ... -
HTML5绘制饼图实例(一)
2011-08-14 15:28 12186HTML5引入Canvas元素 ... -
我的视频教程《中小企业OA系统》
2011-07-29 22:27 7686经过5个月的制作,和华章合作的《中小企业OA系统》Ja ... -
从一道Neusoft题中想到的Java日志API
2011-03-05 09:45 6883先来看看这一季度 ... -
Apache POI组件操作Excel,制作报表(四)
2011-01-04 22:36 9993上一篇我们介绍了如何制作复杂报表的分析和设计,本篇结合 ... -
Apache POI组件操作Excel,制作报表(三)
2010-12-27 23:26 13181上一篇介绍了POI组件操作Excel时如何对单元格和行 ... -
Apache POI组件操作Excel,制作报表(二)
2010-12-19 16:04 18189本文接上一篇继续探究POI组件的使用。 现在来看 ... -
Apache POI组件操作Excel,制作报表(一)
2010-12-16 22:25 42151Apache的POI组件是Jav ... -
使用JACKSON解析JSON(HttpClient 3处理请求)
2010-11-24 18:50 27371在上一篇中,我们 ... -
使用XStream解析XML(使用HttpClient 4发送请求)
2010-11-07 12:55 9524本文意在简单说明XStream解析XML,配合Http ... -
从一道Neusoft题中想到的IO和Comparator
2010-09-23 10:36 2779Neusoft内部定期举 ... -
Spring支持的Quartz程序调度
2010-09-05 21:45 9594开发时有时会有这样一种需求,定期计算某些数据或者执行某 ... -
Servlet 3(用Java生成GET/POST请求)
2010-08-29 10:59 14559Servlet是SUN指定的Java服务器端编程规范, ... -
使用Fusion Charts制作报表(dom4j生成XML)
2010-07-13 13:03 16713首次看到Fusion Charts是在Bug Free ...
相关推荐
下载包含程序源码,lib包,ireport创建模板操作文档,说明。程序可以在java myeclipse环境下直接运行。jasperreport版本6.3.1,ireport为5.6.0
IREPORT使用JAVABEAN作为报表数据源IREPORT使用JAVABEAN作为报表数据源IREPORT使用JAVABEAN作为报表数据源
ireportjasperreport开源报表中使用javabean作为数据源的详细实.docx
实例中通过利用自定义javabean数据源实现报表实例,其中有代码和文档,还有项目中所需要的jar包,不需要重新下载jasper获取jar包
iReport使用JavaBean作为数据源——最简单的示例。 包含: 1、Java源文件(JavaBean)。 2、iReport的报表源文件(jrxml)。 3、详细的说明。
ireport中使用javabean作数据源开发jasperreports报表的详细过程 附有图片
图示ireport中使用javabean作数据源开发基于jasperreports报表过程
ireport利用javabean做数据源.docx
iReport使用JavaBean做数据源
jasperreport报表开发小结,使用ireport设计报表模板,javabean作为数据源,整合springboot实现在线预览和导出各种格式的报表
jasperreport学习 之 javabean封装成list作为数据源.pdf 数据源制作方法,文档里面还包括源码下载地址。
所需要jar包2 博文链接:https://zmx.iteye.com/blog/581075
NULL 博文链接:https://sunnymod.iteye.com/blog/815330
简单明了利用javabean做数据源,实现ireport报表功能
JasperReports作为一种优秀且开源的报表引擎,不利用太...本示例比较简单,采用的数据源即为JavaBean,而没有采用复杂的数据库,其实原理是一样的。只是传递给JasperReports的参数随着连接方式的变化而略加修改而已。