有很多人都说Jasperreports不适合中国式复杂报表,实际上运用好父子报表可以解决大部分问题了。例如下面的表。每个学生的学科数目不固定,且每个学生后有相当于小计的平均分。有点复杂度的报表,可以使用子报表解决。
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)
8.1.2 设计模板表头如下,注意宽度:
8.1.3 新建子模板DemoReport6_sub.jrxml,只保留DetailBand(Height设置为20),并设置模板的宽500,高20,且四周Margin都为0
8.1.4 转到DemoReport6_main主模板,将Subreport组件拖入到Detail中,跳出Subreport界面
8.1.5 将stuNo和stuName拖入到Detail中
8.1.6 转到DemoReport6_sub子模板,新建Fields:subjectName(String)、teacherName(String)、score(java.lang.Double).拖入到Detail中,注意宽度和主模板保持一致
8.1.7 新建Variables,命名为averageScore
拖入到Detail Band中,设置好字体样式
设置TextField的Evaluation Time 选中为Band
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>
保存后:
8.1.10 点击 $F{stuNo} 显示Properties,设置Position Type 为Float,Stretch Type为 ElementGroupHeight,把stuNo和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})点击 Edit Return Values
保存主模板,子模板,放到项目中的jrxml中。
8.2 编写Servlet注入数据源
8.2.1 新建 Student类和Subject类
-
package com.jasper.bean;
-
-
import java.util.ArrayList;
-
import java.util.List;
-
-
public class Student {
-
-
//注意和模板中数据类型保持一致
-
private Integer stuNo;
-
-
private String stuName;
-
-
private List
<Subject> subjectList = new ArrayList
<Subject>();
-
-
// get、set方法省略
-
-
}
-
package com.jasper.bean;
-
-
public
class Subject {
-
-
private String subjectName;
-
-
private String teacherName;
-
-
private
Double score;
-
-
// get、set方法省略
-
-
}
8.2.2 新建JasperServlet6,doGet内容如下:
-
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
-
Map<String,Object> parameters =
new HashMap<String,Object>(
16);
-
-
//组装list数据源
-
Subject sub1 =
new Subject(
"语文",
"张老师",
80.0);
-
Subject sub2 =
new Subject(
"数学",
"王老师",
90.0);
-
Subject sub3 =
new Subject(
"物理",
"孙老师",
46.0);
-
Subject sub4 =
new Subject(
"政治",
"李老师",
50.0);
-
List<Student> list =
new ArrayList<Student>();
-
-
Student stu1 =
new Student();
-
stu1.setStuNo(
101);
-
stu1.setStuName(
"小明");
-
List<Subject> sublist1 =
new ArrayList<Subject>();
-
sublist1.
add(sub1);
-
sublist1.
add(sub2);
-
stu1.setSubjectList(sublist1);
-
-
Student stu2 =
new Student();
-
stu2.setStuNo(
102);
-
stu2.setStuName(
"小雨");
-
List<Subject> sublist2 =
new ArrayList<Subject>();
-
sublist2.
add(sub2);
-
sublist2.
add(sub3);
-
sublist2.
add(sub4);
-
stu2.setSubjectList(sublist2);
-
-
Student stu3 =
new Student();
-
stu3.setStuNo(
103);
-
stu3.setStuName(
"小东");
-
List<Subject> sublist3 =
new ArrayList<Subject>();
-
sublist3.
add(sub4);
-
sublist3.
add(sub3);
-
stu3.setSubjectList(sublist3);
-
-
list.
add(stu1);
-
list.
add(stu2);
-
list.
add(stu3);
-
-
String mainjrxmlPath = request.getServletContext().getRealPath(
"/")+
"/jrxml/DemoReport6_main.jrxml";
-
String subjrxmlPath = request.getServletContext().getRealPath(
"/")+
"/jrxml/DemoReport6_sub.jrxml";
-
//由jrxml文件编译后生产jasper文件的路径
-
String mainjasperPath = request.getServletContext().getRealPath(
"/")+
"/jasper/DemoReport6_main.jasper";
-
String subjasperPath = request.getServletContext().getRealPath(
"/")+
"/jasper/DemoReport6_sub.jasper";
-
-
try {
-
//编译jrxml生产jasper文件
-
JasperCompileManager.compileReportToFile(mainjrxmlPath, mainjasperPath);
-
JasperCompileManager.compileReportToFile(subjrxmlPath, subjasperPath);
-
-
parameters.put(
"title",
"学生成绩表");
-
parameters.put(
"date",
new SimpleDateFormat(
"yyyy-MM-dd").format(
new Date()));
-
String SUBREPORT_DIR = request.getServletContext().getRealPath(
"/")+
"/jasper/";
-
parameters.put(
"SUBREPORT_DIR",SUBREPORT_DIR);
-
-
JasperPrint jasperPrint = JasperFillManager.fillReport(mainjasperPath, parameters,
new JRBeanCollectionDataSource(list));
-
//生成html文件(位置:D:/HTML/student.html)
-
JasperExportManager.exportReportToHtmlFile(jasperPrint,
"D:/HTML/student.html");
-
}
catch (JRException e) {
-
e.printStackTrace();
-
}
-
}