前言
在SpringBoot 集成 Birt中,最后的例子只是比较简单的例子。这篇主要讲述如何去做一个稍微复杂点的report
目标report
要建立一个user report,数据展示分为2部分
第一部分列出所有用用户,第二部分列出用户的详情,详情里包含了用户的不同的account类型,完成后的pdf如下图:
数据结构
后端获取到的数据是一个list<User>
User的数据结构如下,注意user里关联了一个List<Account>
对象
Class User{
private Long userKy;
private String fullName;
private String email;
private String mobile;
private Date birthDay;
private String userId;
private String language;
private String companyName;
private List<Account> accounts;
}
Class Account{
private long key;
private String accountName;
private String accountNo;
private String ccy;
private int paymentType; // 1.payment 2.payroll 3.fix deposit
private int userKy;
}
知识点
- dataSource
- dataset open fetch
- dataSource 和 dataset的关系
- dataset filter
- grid和table 组件的使用
- script使用
- css 使用
- master page 设置页头和页尾
代码流程
- birt工具里新建立1个report,命名为user.rptdesin
- 新建立scripted data Source的DataSource,打开它的script,在initialize 事件输入以下代码。
//获取到spring的上下文
var spring=reportContext.getAppContext().get("spring");
//获取到userReportDataService这个service
var userService=spring.getBean("userReportDataService");
//获取数据,也就说datasource里的数据就是userList
userList=userService.getUsers();
userService的java代码如下
public class UserReportDataService {
//从一个user.json文件里获取到user的list
public List<User> getUsers(){
InputStream is=UserReportDataService.class.getClassLoader().getResourceAsStream("mock/user.json");
try {
ObjectMapper mapper = new ObjectMapper();
JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class,User.class);
List<User> users=mapper.readValue(is,javaType);
return users;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
- 新建立 dataSet ,关联上刚选中的dataSource。命名为users,打开它的script
选中open输入
count=0;
选中fech输入
if(userList.size()>count) {
user=userList.get(count);
row.userId=user.getUserId();
row.fullName=user.getFullName();
row.mobile=user.getMobile();
row.language=user.getLanguage();
row.email=user.getEmail();
row.companyName=user.getCompanyName();
row.birthDay=user.getBirthDay();
row.userKy=user.getUserKy();
count++;
return true;
}
return false;
fetch里的row就是dataset里的一条记录,注意在这里只能插入一条记录。
- 新建立 dataSet ,关联上刚选中的dataSource。命名为userAccount,打开它的script
选中open输入
importPackage(Packages.java.util)
acctArrList = new ArrayList();
for(var i=0;i<userList.size();i++) {
u=userList.get(i);
var accts=u.getAccounts();
if(accts!=null){
j=0;
while(j<accts.size()){
acct=accts.get(j);
acct.setUserKy(u.getUserKy());
acctArrList.add(acct);
j++;
}
}
}
count=0;
由于fetch只能写入1条记录。所以只能先把所有的account拿出来放到一个ArrayList里
选中fech输入
if(acctArrList.size()>count) {
acct=acctArrList.get(count);
row.accountName=acct.getAccountName();
row.accountNo=acct.getAccountNo();
row.ccy=acct.getCcy();
row.key=acct.getKey();
row.paymentType=acct.getPaymentType();
row.userKy=acct.getUserKy();
count++;
return true;
}
return false;
data source和data set 的关系?
data source 是获取到数据的数据源,选中scripted data source就是说通过script的方法来获取到数据,如上第2步的代码。
当数据源获取完毕后,data set通过open 和 fetch操作来从data source里获取到需要的数据集
- 整个report 设计
总共分成1,2,3,4,5张table。
1和2通过一个上下的grid分开
2里的3,4,5 各是一个detail 的row
一个蓝色框就是一个detail的row
rptdesign文件下载
- table 1很简单,拖个table到grid然后选中data set为users.
- table 2 ,拖个table到grid,选中data set为 userAccount , table2里包含了 3,4,5 .
- table 3 是当前行的user的对应account的paymentType=1 的账号
- table 4 是当前行的user的对应account的paymentType=2 的账号
- table 5 是当前行的user的对应account的paymentType=3 的账号
-
以table 3为例讲解,拖个table到图中的位置后,选中data set为userAccounts,该 userAccounts已经在fetch的时候将所有的account放到里面了。注意下面的红色框里的filter条件的使用
-
接下来就是加入css使report美观些
在styles里加入一个css的文件,在下面的框里选择需要导入的style -
修改master page,加入页头和页尾
在最上面加入一个Grid,Grid内容可以参看下载的rptdesign文件 -
加入一个logo图片
add Image加入一张图片,并且选择为Emedded image,这样图片就会嵌入到report的设计文件里。 -
java code
这个和 SpringBoot 集成 Birt基本相同这里不具体说明
整个代码在github code里。 -
运行spring boot后,在postman里输入
http://localhost:8080/report/user
debug 方法
脚本很不好发现问题,目前简单的方法就是在script里打印出来,如下
importPackage(Packages.java.lang);
System.out.println("xxxxx");