11.1 事件机制详解
前面通过脚本获取数据源,以及在报表中利用单元格或者数据项的onRender方法添加脚本来增加交互性,或者直接在脚本编辑器中书写少量代码,或多或少的都利用到了BIRT的脚本和事件机制,但这仅仅只是冰山一角。
BIRT提供了一个基于Mozilla Rhino的脚本模型。报表引擎创建报表的过程可以划分为两个阶段——生成和呈现。生成阶段利用报表设计,生成一个名为报表文档的中间文件。呈现阶段利用报表文档进行渲染,生成HTML或PDF。报表生产线既可以将两个阶段作为一个任务执行,也可以作为两个任务分别执行。如果作为一个任务,那么报表文档是生成在内存中。在设计器中选择『以HTML方式预览』时,默认是采用这种方式的。反之,如果作为两个任务分别执行,那么报表文档将被保存在磁盘中。在设计器中选择『在浏览器中预览』时,默认是采用这种方式的。
每一个阶段的事件都通过事件处理器覆盖,用以修改报表内容。既可以用JavaScript,也可以用Java。
事件:
三大对象——报表对象、报表元素和数据源(集)——具有脚本事件。当前所处的阶段决定了可以定制的事件类型和对象属性。
下图描绘了包含一个表和一个数据元素的简单报表的事件触发顺序:
产生阶段:
展现阶段:
我们以一个报表为例来打印出事件的执行顺序:
我们新建报表javascript_logging_demo.rptdesign,选用脚本数据源,定义数据集,
仅仅只有两列
row_int 整数
row_string 字符串
我们在获取数据集的时候必须书写两个方法:
open方法
rowCount = 0;
fetch方法:
while (rowCount < 5) {
rowCount ++;
row['row_int'] = rowCount;
row['row_string'] = "another string " + rowCount;
return true;
}
把两个数据列拖入一个1行2列的表中,布局报表报表,做适当美化,预览效果如下:
为了查看这个报表的事件执行顺序,我们需要在报表,数据源,数据集,表,行,数据项上书写一系列日志,方法如下:
选择大纲视图,选择报表编辑器的脚本查看选项卡:
我们选中报表名称,在initialize中书写如下的语句:
// INTIALIZE THE LOGGER WITH A FILE BASED LOGGER
importPackage(Packages.java.util.logging);
importPackage(Packages.logging);
var fileHandler = new FileHandler("javascript.log", false);
//fileHandler.setFormatter(new BirtEventFormatter());
var rootLogger = Logger.getLogger("");
rootLogger.addHandler(fileHandler);
function log ( str ){
Logger.getAnonymousLogger().info(str);
}
reportContext.setPersistentGlobalVariable("log", log);
log("Initialize");
说明:源码的含义是生成一个javascript.log文件,用来记录日志信息,并把写日志事件设置成全局常量方法,以便在其他方法中直接调用。
这样,我们在选中数据源,数据集,表,行,单元格,数据项时,即可通过下拉方法框书写一系列日志。
例如在数据源上:
beforeOpen |
log("Data Source Before Open"); |
Open |
log("Data Source Open"); |
beforeClose |
log("Data Source Before Close"); |
close |
log("Data Source Close"); |
afterClose |
log("Data Source After Close"); |
在数据集上
beforeOpen |
log("Data Set Before Open"); |
Open |
log("Data Set Open"); |
fetch |
log("Data Set Fetch"); |
onFetch |
log("Data Set OnFetch"); |
beforeClose |
log("Data Set Before Close"); |
close |
log("Data Set Close"); |
afterClose |
log("Data Set After Close"); |
其它事件类似,不一一举例。
运行报表,我们在eclipse的根目录下可以看到产生的javascript文件:
内容如下:
<?xml version="1.0" encoding="GBK" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780241</millis>
<sequence>170</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Initialize</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780241</millis>
<sequence>171</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Table onPrepare</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780241</millis>
<sequence>172</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Row onPrepare</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780241</millis>
<sequence>173</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Cell onPrepare</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780241</millis>
<sequence>174</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Data onPrepare</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780241</millis>
<sequence>175</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>before factory</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780241</millis>
<sequence>176</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>before render</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780256</millis>
<sequence>177</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Data Source Before Open</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780256</millis>
<sequence>178</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Data Source Open</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780256</millis>
<sequence>179</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Data Source Afger Open</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780256</millis>
<sequence>180</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Data Set BeforeOpen</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780256</millis>
<sequence>181</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Data Set Open</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780256</millis>
<sequence>182</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Data Set AfterOpen</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780256</millis>
<sequence>183</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Data Set Fetch</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780256</millis>
<sequence>184</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Data Set OnFetch</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780256</millis>
<sequence>185</sequence>
<level>INFO</level>
<class>sun.reflect.NativeMethodAccessorImpl</class>
<method>invoke0</method>
<thread>12</thread>
<message>Data Set Fetch</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780256</millis>
<sequence>186</sequence>
<level>INFO</level>
<class>sun.reflect.GeneratedMethodAccessor24</class>
<method>invoke</method>
<thread>12</thread>
<message>Data Set OnFetch</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780256</millis>
<sequence>187</sequence>
<level>INFO</level>
<class>sun.reflect.GeneratedMethodAccessor24</class>
<method>invoke</method>
<thread>12</thread>
<message>Data Set Fetch</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780256</millis>
<sequence>188</sequence>
<level>INFO</level>
<class>sun.reflect.GeneratedMethodAccessor24</class>
<method>invoke</method>
<thread>12</thread>
<message>Data Set OnFetch</message>
</record>
<record>
<date>2013-01-05T10:43:00</date>
<millis>1357353780256</millis>
<sequence>189</sequence>
<level>INFO<