Ireport+struts2+javabean数据源解决子报表问题一直很难搞,前2天我终于解决了。(*^__^*) 嘻嘻……
其实我们一直弄不通,并不是程序的问题,而是报表设计的时候一些参数没有设置正确。把理论搞清楚一切问题迎刃而解。
举个例子说明问题:
一、po类
User.java
Address.java
这个报表想展示的就是一个这样的结果,报表的上半部分为用户的基本信息,下半部门为用户的地址信息,因为用户的联系地址可能有多个,所以我们想到了用子报表的形式来实现。
二、实现的java类
上面代码提供3个方法,第二个方法是本文要讲的内容。userList为主报表数据源,而子报表数据源是作为参数传递的。在ireport中把这 个参数作为子报表的数据源(new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{sublist})) 传递过去
三、配置文件
struts.xml
四、Ireport模板
设计模板的基础知识就不再多说了,说下几个注意的地方
子报表
运行结果
五、未解决问题
我在做这个测试前看了一个帖子,帖子的说明的是ireport以javabean为数据源解决子报表问题,用的是 javabean+sevlet的结构。使用的方法和我提供的reportUserAllInfo原理相同,但是这个方法在struts2这个框架下没有 测试通过(在我这里是这样的)。有没有人知道怎么解决?
Bug如下:
六、%>_<%,上传不了了呐。不过代码都贴出来了,lib文件的下载在struts2+ireport学习小结(一)和(二)中。 http://hanxin830311.iteye.com/blog/763511和http://hanxin830311.iteye.com /blog/763628
其实我们一直弄不通,并不是程序的问题,而是报表设计的时候一些参数没有设置正确。把理论搞清楚一切问题迎刃而解。
举个例子说明问题:
一、po类
User.java
- package com.ansure.moudle;
- import java.util.List;
- public class User {
- private int u_id;
- private String u_name;
- private String u_pwd;
- private List addresses;
- public User() {
- }
- public User(int id, String name, String pwd, List addresses) {
- this.u_id = id;
- this.u_name = name;
- this.u_pwd = pwd;
- this.addresses = addresses;
- }
- public int getU_id() {
- return u_id;
- }
- public void setU_id(int uId) {
- u_id = uId;
- }
- public List getAddresses() {
- return addresses;
- }
- public void setAddresses(List addresses) {
- this.addresses = addresses;
- }
- public String getU_name() {
- return u_name;
- }
- public void setU_name(String uName) {
- u_name = uName;
- }
- public String getU_pwd() {
- return u_pwd;
- }
- public void setU_pwd(String uPwd) {
- u_pwd = uPwd;
- }
- }
Address.java
- package com.ansure.moudle;
- public class Address {
- private User user;
- private String address;
- private String zip;
- private String email;
- /**
- *
- */
- public Address() {
- super();
- // TODO Auto-generated constructor stub
- }
- /**
- * @param address
- * @param zip
- * @param email
- */
- public Address(User user, String address, String zip, String email) {
- this.user = user;
- this.address = address;
- this.zip = zip;
- this.email = email;
- }
- public String getAddress() {
- return address;
- }
- public void setAddress(String address) {
- this.address = address;
- }
- public String getEmail() {
- return email;
- }
- public void setEmail(String email) {
- this.email = email;
- }
- public User getUser() {
- return user;
- }
- public void setUser(User user) {
- this.user = user;
- }
- public String getZip() {
- return zip;
- }
- public void setZip(String zip) {
- this.zip = zip;
- }
- }
这个报表想展示的就是一个这样的结果,报表的上半部分为用户的基本信息,下半部门为用户的地址信息,因为用户的联系地址可能有多个,所以我们想到了用子报表的形式来实现。
二、实现的java类
- package com.ansure.action;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import com.ansure.moudle.Address;
- import com.ansure.moudle.User;
- import com.opensymphony.xwork2.ActionSupport;
- public class TestAction extends ActionSupport {
- private static final long serialVersionUID = 1L;
- private List<User> userList = new ArrayList<User> ();
- public Map<String,Object> map = new HashMap<String,Object>();
- //普遍报表
- public String reportUserInfo() {
- try {
- userList= getDateSouce();
- } catch (Exception e) {
- e.printStackTrace();
- return ERROR;
- }
- return SUCCESS;
- }
- //带子报表的报表,通过参数传递子报表数据源
- public String reportUserAddress(){
- try {
- userList= getDateSouce();
- List sublist = getSubDateSouce();
- map.put("sublist", sublist);
- } catch (Exception e) {
- e.printStackTrace();
- return ERROR;
- }
- return SUCCESS;
- }
- // 带子报表的报表,通过主报数据源对象的属性参数传递子表数据源(不可行)
- public String reportUserAllInfo(){
- try {
- userList= getAllDateSouce();
- } catch (Exception e) {
- e.printStackTrace();
- return ERROR;
- }
- return SUCCESS;
- }
- private List getDateSouce()throws Exception{
- List list = new ArrayList();
- try{
- User user = new User();
- user.setU_id(1);
- user.setU_name("吴明");
- user.setU_pwd("123456");
- list.add(user);
- return list;
- }catch(Exception e){
- e.printStackTrace();
- return null;
- }
- }
- private List getSubDateSouce()throws Exception{
- List sublist = new ArrayList();
- try{
- Address add1 = new Address();
- add1.setZip("100000");
- add1.setAddress("北京市**********");
- add1.setEmail("emailname@mailserver.com");
- sublist.add(add1);
- Address add2 = new Address();
- add2.setZip("200000");
- add2.setAddress("上海市**********");
- add2.setEmail("emailname@mailserver.com");
- sublist.add(add2);
- Address add3 = new Address();
- add3.setZip("300000");
- add3.setAddress("天津市**********");
- add3.setEmail("emailname@mailserver.com");
- sublist.add(add3);
- return sublist;
- }catch(Exception e){
- e.printStackTrace();
- return null;
- }
- }
- private List getAllDateSouce()throws Exception{
- List list = new ArrayList();
- List sublist = new ArrayList();
- try{
- User user1 = new User();
- user1.setU_id(1);
- user1.setU_name("吴明");
- user1.setU_pwd("123456");
- Address add1 = new Address();
- add1.setZip("100000");
- add1.setAddress("北京市**********");
- add1.setEmail("emailname@mailserver.com");
- sublist.add(add1);
- Address add2 = new Address();
- add2.setZip("200000");
- add2.setAddress("上海市**********");
- add2.setEmail("emailname@mailserver.com");
- sublist.add(add2);
- Address add3 = new Address();
- add3.setZip("300000");
- add3.setAddress("天津市**********");
- add3.setEmail("emailname@mailserver.com");
- sublist.add(add3);
- user1.setAddresses(sublist);
- list.add(user1);
- User user2 = new User();
- user1.setU_id(2);
- user1.setU_name("张三");
- user1.setU_pwd("121212");
- List sublist2 = new ArrayList();
- sublist2.add(add3);
- sublist2.add(add2);
- user2.setAddresses(sublist2);
- list.add(user2);
- return list;
- }catch(Exception e){
- e.printStackTrace();
- return null;
- }
- }
- public List<User> getUserList() {
- return userList;
- }
- public void setUserList(List<User> userList) {
- this.userList = userList;
- }
- public Map<String, Object> getMap() {
- return map;
- }
- public void setMap(Map<String, Object> map) {
- this.map = map;
- }
- }
上面代码提供3个方法,第二个方法是本文要讲的内容。userList为主报表数据源,而子报表数据源是作为参数传递的。在ireport中把这 个参数作为子报表的数据源(new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{sublist})) 传递过去
三、配置文件
struts.xml
- <struts>
- <!-- 设置使用JasperReports的Action -->
- <package name="C06.3"
- extends="struts-default,jasperreports-default">
- <action name="reportUserInfo" class="com.ansure.action.TestAction" method="reportUserInfo">
- <!-- result类型设置为jasper -->
- <result name="success" type="jasper">
- <!-- 编译后的jasper文件路径 -->
- <param name="location">
- /jasperreports/testReport.jasper
- </param>
- <!-- 视图界面中显示的数据的数据源 -->
- <param name="dataSource">userList</param>
- <!-- 报表生成格式 -->
- <param name="format">PDF</param>
- </result>
- </action>
- <action name="reportUserAddress" class="com.ansure.action.TestAction" method="reportUserAddress">
- <!-- result类型设置为jasper -->
- <result name="success" type="jasper">
- <!-- 编译后的jasper文件路径 -->
- <param name="location">
- /jasperreports/test_mainReport.jasper
- </param>
- <!-- 视图界面中显示的数据的数据源 -->
- <param name="dataSource">userList</param>
- <param name="reportParameters">map</param>
- <!-- 报表生成格式 -->
- <param name="format">PDF</param>
- </result>
- </action>
- <action name="reportUserAllInfo" class="com.ansure.action.TestAction" method="reportUserAllInfo">
- <!-- result类型设置为jasper -->
- <result name="success" type="jasper">
- <!-- 编译后的jasper文件路径 -->
- <param name="location">
- /jasperreports/testReport.jasper
- </param>
- <!-- 视图界面中显示的数据的数据源 -->
- <param name="dataSource">userList</param>
- <!-- 报表生成格式 -->
- <param name="format">PDF</param>
- </result>
- </action>
- </package>
- </struts>
四、Ireport模板
设计模板的基础知识就不再多说了,说下几个注意的地方
- 建议以javabean作为数据源时,主报表和子报表模板分别设计比较好。主报表添加子报表时选择已存在的子报表就可以了。
- 因为程序为主报表传过来一个参数,比如sublist,所以要在主报表中添加参数sublist,并且通过参数属性界面更改参数类型(默认为String类型的),更改为java.lang.List.
- 打开在主报表中添加的子报表控件的属性面板,查看connection type 属性,选择Use a datasource expression 选项[*]打开在主报表中添加的子报表控件的属性面板,查看Data Source Expression属性,填写new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{sublist})。。
- 如果有多个子报表,需要顺序输出到页面,而且你又不确定每个子报表的所占高度,那么建议把子报表放在分组中。分组时可以添加多个header和fooder的,所以你也可以添加多个子报表。
子报表
运行结果
五、未解决问题
我在做这个测试前看了一个帖子,帖子的说明的是ireport以javabean为数据源解决子报表问题,用的是 javabean+sevlet的结构。使用的方法和我提供的reportUserAllInfo原理相同,但是这个方法在struts2这个框架下没有 测试通过(在我这里是这样的)。有没有人知道怎么解决?
Bug如下:
引用
javax.servlet.ServletException: Error evaluating expression :
Source text : new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{addresses})
Source text : new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{addresses})
引用
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'org.apache.struts2.views.jasperreports.ValueStackDataSource@1159cd1' with class 'org.apache.struts2.views.jasperreports.ValueStackDataSource' to class 'java.util.List'
org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:340)
org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:340)
六、%>_<%,上传不了了呐。不过代码都贴出来了,lib文件的下载在struts2+ireport学习小结(一)和(二)中。 http://hanxin830311.iteye.com/blog/763511和http://hanxin830311.iteye.com /blog/763628
相关推荐
3. **创建javaBean数据源**:javaBean是一种简单的Java对象,它封装了数据并提供了访问这些数据的方法。在本例中,你需要创建一个包含所需数据的javaBean类,比如一个包含了多个属性(对应报表中的列)的对象。 4. ...
总之,使用Struts2、JasperReport和iReport开发报表时,要关注数据源配置、中文支持、Struts2与报表之间的交互以及子报表的参数传递。遇到问题时,多参考官方文档、社区资源,结合错误信息进行排查,往往能找到合适...
要配置iReport以使用JavaBean数据源,首先需要确保JavaBean已经被正确编译并添加到Classpath中。这可以通过以下步骤实现: 1. 打开iReport,选择“Options”菜单,然后点击“Classpath”。 2. 在弹出的窗口中,你...
- 配置报表查询,选取JavaBean数据源并指定Bean类路径,读取Bean的属性。 - 设计报表布局,包括字段选择和样式设置。 - 编译报表,生成`.jasper`文件,这一步完成后,iReport的工作基本结束。 5. MyEclipse创建工程...
JasperReports是一个强大的报表引擎,能够处理各种复杂的数据源,如SQL查询结果、CSV文件、XML数据等,并将其转换为精美的报表。iReport允许用户通过直观的图形界面设计报表布局,包括表格、图表、文本框等元素,还...
**3.2 建立JavaBean数据源** 接着,点击工具栏上的“New”按钮,选择“JavaBeans set data source”,然后单击“Next”。 **3.3 配置JavaBean** 在此步骤中,需要输入JavaBean的类名和路径,例如`...
模板中可以包含静态文本、图片、表格等元素,并通过SQL查询或JavaBean数据源绑定动态数据。 3. **配置Struts2**:在Struts2的配置文件(struts.xml)中,定义一个Action,该Action将负责加载报表并将其导出。Action...
4. **生成报表**:在Action中,我们需要加载报表模板,设置数据源(通常是Action中的JavaBean集合),然后使用JasperReport API生成报表。这通常涉及以下步骤: ```java // 在ReportAction的execute方法中 Map ...
2. **动态创建报表**:在代码中动态构建JRDataSource,然后使用JasperFillManager填充报表,这种方式适用于数据源不确定或动态变化的情况。 3. **使用JSP嵌入式报表**:直接在JSP页面中嵌入报表,通过JavaBean或...
Action可以通过JDBC连接数据库获取数据,也可以使用Java对象作为数据源。填充完成后,Action可以将报表流返回给客户端,通过设置Struts2的结果类型为"stream",可以实现报表的下载。 **集成步骤** 1. 添加...
4. **JRDataSource**: 数据源接口,用于将数据提供给报表进行填充,可以是数据库连接、集合、JavaBean等。 5. **JasperFillManager**: 负责根据数据源填充报表的对象。 6. **JasperExportManager**: 处理报表导出,...
struts2下使用JasperReports5.0.1一个简单示例,html、xml、pdf可正常显示。html修复无法显示图片问题。ireport数据源采用javabean和jdbc两种方式。