http://blog.runqian.com.cn/?p=1502
报表数据经常来源于多个数据源,如多个数据库、文件、分布式文件系统等。传统报表工具往往要借助第三方程序(如JAVA自定义数据源)完成,实现复杂,同时导致应用系统与报表系统的耦合度过高导致维护困难。润乾集算报表除了提供自定义数据源支持外,还可以使用脚本数据集直接在报表内使用多数据源。下面分别来看一下两种方法的实现方式。
业务系统中将订单信息存储到JSON格式的文件中,报表查询时需要读取JSON格式文件与数据库表(维表)进行联合查询。这里以查询某发货时间段内所有订单的客户信息为例。
orders.json部分内容如下:
{
”orders”:[
{
"订单ID": "10248",
"订单编号": [
{
"订单ID": "10248",
"产品ID": "5",
"单价": 12,
"折扣": 0,
"数量": 1
}
],
“客户ID”: “VINET”,
“发货日期”: “2000-07-16″,
“到货日期”: “1996-08-01″,
“运货费”: 32.38
},
……
{
“订单ID”: “10400″,
“客户ID”: “EASTC”,
“发货日期”: “1997-01-16″,
“到货日期”: “1997-01-29″,
“运货费”: 83.93
}
]
}
目标报表格式:
左半部分来源订单JSON文件;右半部分来源数据库客户表;二者通过客户编号关联。
自定义数据集实现
连接数据源
在报表设计器中连接数据源:
设置报表参数
新建报表,并设置报表参数(发货起止日期)。
设置报表数据集
其中ds1为自定义数据集,用于解析JSON文件:
ds2为SQL数据集,读取数据库客户表信息:
SELECT * FROM 客户
JSONDataSet.java内容如下:
public class JSONDataSet implements IDataSetFactory {
public DataSet createDataSet(Context ctx, DataSetConfig dsc,
boolean retrieve) {
// 取得参数列表并分别取得它的参数名与值,宏与之类似
Map map = ctx.getParamMap(false);
String begin = null;
String end = null;
if (map != null) {
begin = map.get(“begin”).toString();
end = map.get(“end”).toString();
}
DataSet ds1 = new DataSet(“ds1″);
String[] filds = { “订单ID”, “发货日期”, “客户ID” };
for (int i = 0; i < filds.length; i++) {
ds1.addCol(filds[i]);// 设置数据集的字段
}
String JsonContext = new JSONDataSet().ReadFile(“D:\\orders.json”);
try {
JSONObject jo = new JSONObject(JsonContext);
JSONArray ja = jo.getJSONArray(“orders”);
for (int i = 0; i < ja.length(); i++) {
String tdate = ja.getJSONObject(i).getString(“发货日期”);
if (tdate.compareTo(begin) >= 0 && end.compareTo(tdate) >= 0) {
Row rr = ds1.addRow();
String id = ja.getJSONObject(i).getString(“订单ID”);
String cusid = ja.getJSONObject(i).getString(“客户ID”);
rr.setData(1, id);
rr.setData(2, tdate);
rr.setData(3, cusid);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return ds1;
}
public String ReadFile(String Path) {
BufferedReader reader = null;
String laststr = “”;
try {
FileInputStream fileInputStream = new FileInputStream(Path);
InputStreamReader inputStreamReader = new InputStreamReader(
fileInputStream, “GBK”);
reader = new BufferedReader(inputStreamReader);
String tempString = null;
while ((tempString = reader.readLine()) != null) {
laststr += tempString;
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return laststr;
}
}
这里使用了json_org.jar解析JSON串,使用时需要引入。
编辑报表表达式
至此,通过自定义数据集实现完成。可以看到,集算报表提供了自定义数据集接口提供了较大的灵活性,用户可以自由编写代码完成数据源准备;但由于编码复杂(本例中只在JAVA程序中解析JSON串并过滤,代码已经很长,如果再完成关联运算将会更加复杂)使得自定义数据源的方式使用难度较大。另外,报表必须和程序代码一同部署导致报表与应用中耦合度过高,未来修改维护成本过高。
集算报表提供的脚本数据集可以很好解决上述问题,下面来看实现。
脚本数据集实现
报表参数设置如上。
设置数据集
在数据集设置窗口选择“脚本数据集”,编写脚本同时读取JSON格式文件和数据库表完成关联查询,十分简单:
A1:读取订单信息JSON格式文件。
A2:根据发货日期范围过滤数据。
A3:查询数据库客户表信息。
A4:根据客户ID关联文件和数据表,完成混合计算。
A5:根据关联结果新建结果集,并返回给报表。
编辑报表表达式
根据脚本数据集返回的结果,编写如下报表表达式,完成报表制作。
使用脚本数据集除了可以避免上述提到的编写困难、耦合度高等问题,由于关联运算在脚本中完成,相比使用报表表达式关联效率更高。