Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

       有很多人都说Jasperreports不适合中国式复杂报表,实际上运用好父子报表可以解决大部分问题了。例如下面的表。每个学生的学科数目不固定,且每个学生后有相当于小计的平均分。有点复杂度的报表,可以使用子报表解决。

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

8.1 设计报表模板

 

8.1.1 新建主模板DemoReport6_main.jrxml,创建Paramters :title(java.lang.String)、date(java.lang.String)、SUBREPORT_DIR(java.lang.String),创建Fields :stuNo(java.lang.Integer)、

stuName(java.lang.String)、subjectList(java.util.List)

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

8.1.2 设计模板表头如***意宽度:

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

8.1.3 新建子模板DemoReport6_sub.jrxml,只保留DetailBand(Height设置为20),并设置模板的宽500,高20,且四周Margin都为0

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

8.1.4 转到DemoReport6_main主模板,将Subreport组件拖入到Detail中,跳出Subreport界面

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

8.1.5 将stuNo和stuName拖入到Detail中

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

8.1.6 转到DemoReport6_sub子模板,新建Fields:subjectName(String)、teacherName(String)、score(java.lang.Double).拖入到Detail中,注意宽度和主模板保持一致

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

8.1.7 新建Variables,命名为averageScore

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

8.1.8 转回DemoReport6_mian主模块,新建Variables,命名为getAverageScore

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

拖入到Detail Band中,设置好字体样式

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

点击 $V{getAverageScore} 显示Properties,设置Appearance中Position Type选中为Fix Relation To Bottom(同样将“平均分”如此设置)

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

设置TextField的Evaluation Time 选中为Band

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

8.1.9 将Subreport、$F{stuNo}、$F{stuName}放进一个Element Group里,直接在source中添加(未找到图形化操作)

 

<detail>

       ...

           <elementGroup>

              <subreport>

                  ...

              </subreport>

              <textField>

                  ... <textFieldExpression><![CDATA[$F{stuNo}]]></textFieldExpression>

              </textField>

              <textField>

                  ...

                  <textFieldExpression><![CDATA[$F{stuName}]]></textFieldExpression>

              </textField>

           </elementGroup>

       ...

    </detail>

保存后:

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

 

8.1.10 点击 $F{stuNo} 显示Properties,设置Position Type 为Float,Stretch Type为 ElementGroupHeight,把stuNo和Subreport也如此设置。

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

8.1.11 点击Subreport 显示Properties,在Subreport中设置Exception为$P{SUBREPORT_DIR}+"DemoReport6_sub.jasper",Data Source Expression为

newnet.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{subjectList})

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

点击 Edit Return Values

 

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)

 

 

保存主模板,子模板,放到项目中的jrxml中。

 

 

8.2 编写Servlet注入数据源

 

 

8.2.1 新建 Student类和Subject类

 

 

 
  1. package com.jasper.bean;

  2.  
  3. import java.util.ArrayList;

  4. import java.util.List;

  5.  
  6. public class Student {

  7.  
  8. //注意和模板中数据类型保持一致

  9. private Integer stuNo;

  10.  
  11. private String stuName;

  12.  
  13. private List<Subject> subjectList = new ArrayList<Subject>();

  14.  
  15. // get、set方法省略

  16.  
  17. }

 
  1. package com.jasper.bean;

  2.  
  3. public class Subject {

  4.  
  5. private String subjectName;

  6.  
  7. private String teacherName;

  8.  
  9. private Double score;

  10.  
  11. // get、set方法省略

  12.  
  13. }

 

 

8.2.2 新建JasperServlet6,doGet内容如下:

 

 

 
  1. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

  2.  
  3. Map<String,Object> parameters = new HashMap<String,Object>(16);

  4.  
  5. //组装list数据源

  6. Subject sub1 = new Subject("语文","张老师",80.0);

  7. Subject sub2 = new Subject("数学","王老师",90.0);

  8. Subject sub3 = new Subject("物理","孙老师",46.0);

  9. Subject sub4 = new Subject("政治","李老师",50.0);

  10. List<Student> list = new ArrayList<Student>();

  11.  
  12. Student stu1 = new Student();

  13. stu1.setStuNo(101);

  14. stu1.setStuName("小明");

  15. List<Subject> sublist1 = new ArrayList<Subject>();

  16. sublist1.add(sub1);

  17. sublist1.add(sub2);

  18. stu1.setSubjectList(sublist1);

  19.  
  20. Student stu2 = new Student();

  21. stu2.setStuNo(102);

  22. stu2.setStuName("小雨");

  23. List<Subject> sublist2 = new ArrayList<Subject>();

  24. sublist2.add(sub2);

  25. sublist2.add(sub3);

  26. sublist2.add(sub4);

  27. stu2.setSubjectList(sublist2);

  28.  
  29. Student stu3 = new Student();

  30. stu3.setStuNo(103);

  31. stu3.setStuName("小东");

  32. List<Subject> sublist3 = new ArrayList<Subject>();

  33. sublist3.add(sub4);

  34. sublist3.add(sub3);

  35. stu3.setSubjectList(sublist3);

  36.  
  37. list.add(stu1);

  38. list.add(stu2);

  39. list.add(stu3);

  40.  
  41. String mainjrxmlPath = request.getServletContext().getRealPath("/")+"/jrxml/DemoReport6_main.jrxml";

  42. String subjrxmlPath = request.getServletContext().getRealPath("/")+"/jrxml/DemoReport6_sub.jrxml";

  43. //由jrxml文件编译后生产jasper文件的路径

  44. String mainjasperPath = request.getServletContext().getRealPath("/")+"/jasper/DemoReport6_main.jasper";

  45. String subjasperPath = request.getServletContext().getRealPath("/")+"/jasper/DemoReport6_sub.jasper";

  46.  
  47. try {

  48. //编译jrxml生产jasper文件

  49. JasperCompileManager.compileReportToFile(mainjrxmlPath, mainjasperPath);

  50. JasperCompileManager.compileReportToFile(subjrxmlPath, subjasperPath);

  51.  
  52. parameters.put("title", "学生成绩表");

  53. parameters.put("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));

  54. String SUBREPORT_DIR = request.getServletContext().getRealPath("/")+"/jasper/";

  55. parameters.put("SUBREPORT_DIR",SUBREPORT_DIR);

  56.  
  57. JasperPrint jasperPrint = JasperFillManager.fillReport(mainjasperPath, parameters, new JRBeanCollectionDataSource(list));

  58. //生成html文件(位置:D:/HTML/student.html)

  59. JasperExportManager.exportReportToHtmlFile(jasperPrint, "D:/HTML/student.html");

  60. } catch (JRException e) {

  61. e.printStackTrace();

  62. }

  63. }

 

 

 

8.3 启动tomcat,访问servlet,查看html文件

Jasperreports+jaspersoft studio学习教程(八)- 子报表Subreport(父子报表互相传值)