实际业务中经常有一些报表数据来源于文件而非数据库,如:计算应发工资报表用到考勤数据文件、用户行为分析类报表用到的日志文件、股票分析类报表用到的股票交易记录文件等。由于报表一般都带有参数,经常需要对原始数据进行分组、过滤等,而文件不象数据库那样具备计算能力,需要再编写程序代码才能满足有参数报表的查询需求。
润乾报表使用文件数据源,使用Java程序处理文件,通过自定义数据集为报表提供数据源支持。这里通过一个实例说明润乾报表实现过程,以及改进方式。
数据文件为每个月个月的股价信息(每个月一个文件,文件命名方式为”stock_record_yyyyMM”,如:stock_record_200901.txt、stock_record_200902.txt…),包括每只股票的股票编码、交易日期和收盘价,报表参数为起始年月和结束年月,报表按照交易日排序,展现股票交易记录列表。
Txt文件部分内容如下:
code tradingDate price
120089 2009-01-01 00:00:00 50.24
120123 2009-01-01 00:00:00 10.35
120136 2009-01-01 00:00:00 43.37
120141 2009-01-01 00:00:00 41.86
120170 2009-01-01 00:00:00 194.63
报表格式如下:
1、首先在自定义数据集中接收并解析报表参数,判断使用哪些文件;
Mapmap = ctx.getParamMap(false);
Stringbegin = map.get("begin").toString();
Stringend = map.get("end").toString();
2、定义股票类用于存储股票交易信息
class Stock {
//省略构造函数和get set方法
private String code;
private String tradingDate;
private String price;
}
3、逐行读入文件,使用tab拆分记录,并将字段内容存入List
List<Stock>list = newArrayList<Stock>();
BufferedReaderreader = null;
String[]fields = null;
try {
reader= newBufferedReader(newFileReader(file));
StringtempString = null;
int line = 1;
// 一次读入一行,直到读入null为文件结束
while ((tempString =reader.readLine()) != null) {
// 显示行号
String[]strArr = tempString.split("\\t");// 按tab分割
if(line==1){
for(int i=0;i<strArr.length;i++){
fields= strArr;
}
}else{
list.add(new Stock(strArr[0],strArr[1], strArr[2]));
}
line++;
}
reader.close();
4、定义排序类,实现compare方法比较交易日期
publicclass ComparatorStock implementsComparator {
publicint compare(Objecto1,Object o2){
Stockstock1 = (Stock)o1;
Stockstock2 = (Stock)o2;
returnstock1.getTradingDate().compareTo(stock2.getTradingDate());
}
}
5、使用Collections.sort完成List排序
ComparatorStockcs = newComparatorStock();
Collections.sort(list,cs);
6、创建数据集,并根据排序后List内容设置数据集数据
//构造一个数据集ds1,设置列名
DataSet ds1 = new DataSet("ds1");
for(int i=0;i<fields.length;i++){
ds1.addCol(fields[i]);
}
//设置数据集中的数据
for(int i = 1; i <list.size(); i ++ ){
Stockstock = list.get(i);
Rowrr = ds1.addRow();
rr.setData(1,stock.getCode());
rr.setData(2,stock.getTradingDate());
rr.setData(3,stock.getPrice());
}
报表使用自定义数据集类型:
设置报表模板及表达式:
通过上述步骤可以完成本例的报表需求,润乾报表支持用户自定义数据集处理数据,体现了极大的灵活性。但过于依赖Java编程无疑增加了报表开发的难度,本例只是简单的完成了文件读取和排序,当包含分组、连接等计算时程序的复杂度会陡然上升,对报表开发人员来说都是不小的挑战。当然也可以用报表工具来完成排序等运算,但这样会导致占用较大的内存(特别是有过滤动作时,需要把数据都取到报表端再执行过滤),性能也会受到较大影响,有许多复杂的文件操作也会超出报表工具的计算能力范围。
这种情况下,采用润乾报表基础上的计算强化版集算报表是个不错的选择。集算报表内置的集算器可以帮助集算报表快速完成文件数据源报表。本例在集算报表中可以这样完成。
首先使用集算完成文件读入和排序,集算脚本如下:
A1:根据起始结束月份参数列出中间包含的月份;
A2:根据A1的计算结果,逐个读入月份文件,并将结果合并;
A3:为报表返回按照交易日期排序后结果。
数据集设置
集算报表中使用集算器数据集类型,选择上面编辑好的集算器脚本文件:
报表模板及表达式
上述实现过程可以看到,相比当前版本的润乾报表需要大量依靠Java程序实现,使用集算报表的实现非常简单,集算器脚本的实现代码只有三行,而自定义数据集则需要近200行。集算报表让文件拥有了计算能力,使得开发文件数据源报表更为简单方便。
此外,对于简单的脚本,可以直接使用集算报表内置的“脚本数据集”类型,而不必在单独的集算器脚本中编辑后,通过报表调用。使用脚本数据集的实现方式如下:
1、在数据集设置窗口中点击“增加”按钮,弹出数据集类型对话框,选择“脚本数据集”:
2、在弹出的脚本数据集编辑窗口中编写集算脚本:
脚本数据集中可以直接使用报表定义的参数,如上述脚本中的begin、end即为报表参数。
3、报表调用,与其他数据集使用方式一致,不再赘述。