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</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>190</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>191</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>192</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>193</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>1357353780272</millis>
- <sequence>194</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Table onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>195</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Table onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>196</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>197</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>198</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>199</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>200</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>201</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>202</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>203</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>204</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>205</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>206</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>207</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>208</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>209</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>210</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>211</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>212</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>213</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>214</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>215</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>216</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>217</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>218</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>219</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>220</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>221</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>222</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>223</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>224</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onCreate</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>225</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onRender</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>226</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Data Set BeforeClose</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>227</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Data Set Close</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780272</millis>
- <sequence>228</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Data Set AfterOpen</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780288</millis>
- <sequence>229</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Table onPageBreak</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780288</millis>
- <sequence>230</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onPageBreak</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780288</millis>
- <sequence>231</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onPageBreak</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780288</millis>
- <sequence>232</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onPageBreak</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780288</millis>
- <sequence>233</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onPageBreak</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780288</millis>
- <sequence>234</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Row onPageBreak</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780288</millis>
- <sequence>235</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>after render</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780288</millis>
- <sequence>236</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Data Source Before Close</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780288</millis>
- <sequence>237</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Data Source Close</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780288</millis>
- <sequence>238</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>Data Source After Close</message>
- </record>
- <record>
- <date>2013-01-05T10:43:00</date>
- <millis>1357353780288</millis>
- <sequence>239</sequence>
- <level>INFO</level>
- <class>sun.reflect.GeneratedMethodAccessor24</class>
- <method>invoke</method>
- <thread>12</thread>
- <message>after factory</message>
- </record>
- </log>
从message标签我们可以看到各个方法的执行顺序和执行时间。
11.2 javascript事件绑定
reportContext和this:
在使用Script编辑器时,如果选择Pallette View,那么会显示选定的报表元素、指定事件中能够使用的函数和变量。例如,下图指出了某个数据元素的onCreate事件能够使用的函数和变量:
this可用于在事件中列出元素的所有方法和属性。
reportContext则可以用于访问和修改报表一级的属性。开发人员可用它来设置全局变量。例如:
报表的onInitialize事件
reportContext.setPersistentGlobalVariable("testglobal", "test global string");
用Persistent版本的方法能让变量跨持久化。变量是Object类型的,具有高度的灵活性。
某个表中一个标签的onPrepare事件
this.text = reportContext.getPersistentGlobalVariable('testglobal');
全局变量可以通过绑定编辑器赋给数据元素。只需在给定列的表达式构建器中引用该变量即可。例如,如果绑定编辑器中有一列,其值从数据库取回。那么可以通过以下的表达式,在原值后附加上某个全局变量的值:
dataSetRow["MyString"] + "-" + reportContext.getPersistentGlobalVariable('testglobal');
reportContext也可用于访问会话级变量。
// attributeBean是Birt Viewer提供的一个会话级变量
myAttributeBean = reportContext.getHttpServletRequest.getAttribute('attributeBean');
reportDoc = myAttributeBean.getReportDocumentName();
this.text = reportDoc;
reportContext允许访问和修改脚本内使用的上下文。例如:
报表的onInitialize事件
appContext = reportContext.getAppContext();
importPackage(Packages.java.util)
myArrList = new ArrayList();
myArrList.add("one");
myArrList.add("two");
appContext.put("AppContextTest", myArrList);
这段代码读取了当前的应用上下文,并进行了一些修改。然后,可以在某个标签元素的onPrepare事件处理器中,这样使用:
appContext = reportContext.getAppContext();
myObject = appContext.get("AppContextTest");
this.text = myObject.size();
上例也可以这样实现:
reportContext.setPersistentGlobalVariable("testglobal", myArrList);
reportContext还可用于获取当前的区域信息,以及存储于资源文件中的消息。
报表级事件
afterFactory |
结束生成阶段时执行 |
afterRender |
结束呈现阶段时执行 |
beforeFactory |
开始生成阶段前执行 |
beforeRender |
开始呈现阶段前执行 |
initialize |
开始生成阶段和呈现阶段前执行 |
在initialize事件中,可以定义全局函数、变量和对象。例如,创建一个全局的函数:
function gTest(v){
return "Global Function:" + v;
}
// 仅在图表脚本中使用时需要
reportContext.setPersistentGlobalVariable("gTest", gTest);
只需这样调用:
gTest("MyTest");
或:
gTest = reportContext.getPersistentGlobalVariable("gTest");
val = gTest("Use Persistent");
在图表脚本中访问reportContext时,使用:
context.getExternalContext().getScriptable()
如,图表标题可以这样修改:
- function beforeGeneration(chart, context){
- importPackage(Packages.org.eclipse.birt.chart.model.type.impl);
- newChartTitle = context.getExternalContext().getScriptable().getPersistentGlobalVariable("testglobal");
- chart.getTitle().getLabel().getCaption().setValue(newChartTitle);
- }
在beforeFactory中,有几个方法可以用于访问报表中的元素。需要对元素命名。例如,想要在动态文本元素"TestHeader"中显示数据集"orders"的查询语句,可以在beforeFactory中这样写:
query = this.getDataSet("orders").queryText
this.getDynamicText("TestHeader").valueExpr = "query;";
报表元素级事件
onPrepare |
生成阶段中,为每个报表元素调用一次。可用于修改设计。变更影响元素的所有实例,例如,所有的表行。 |
onCreate |
生成阶段中调用。可访问和修改元素的某个实例(如,每隔9行设置1行背景为红色) |
onRender |
呈现阶段中调用。类似于onCreate。不可访问数据。 |
一个非常简单的例子——某表中的明细行:
onPrepare:
this.getStyle().backgroundColor = "red"; // 影响所有行
onCreate:
if (this.getRowData().getExpressionValue(3) > 100)
this.getStyle().backgroundColor = "red"; // 只影响该行
如果该表中有100行,则onPrepare只调用1次,而onCreate和onRender将调用100次。
元素级事件实例
设置标签、文本、动态文本和数据元素的值
标签:onPrepare/onCreate
this.text = "My New Label"
文本:
this.context = "My New Text"
动态文本:
this.valueExpr = "row['CITY']";
this.valueExpr = "'my row count: ' + (row[0] + 1)";
数据元素:
使用绑定编辑器。
设置TOC
类似于值表达式,期待字符串:
this.tocExpression = "'tocbyrownumber: ' + row[0]";
使用行数据
在onCreate中可使用行数据,可用于对值进行检查。
this.getRowData().getExpressionValue(i) // 第i列的值
this.getRowData().getExpressionValue("some_expression") // 对该行套用表达式的值
例如:
- if (this.getRowData().getExpressionValue(1) == "product1")
- this.getStyle().backgroundColor = "red";
- if (this.getRowData().getExpressionValue("row[price]" == "$30")
- this.getStyle().backgroundColor = "blud";
修改超链接
可在onPrepare中修改:
this.getAction().URI = "'http://www.google.com'";
getStyle
用于定制给定元素的属性。例如:
this.getStyle().fontWeight = "bold";
getParent
用于访问父元素。例如,从数据元素获取表:
this.getParent().getParent().getParent();
父子层级如下:dataElement->Cell->Row->Table
所以如果你想从一个数据元素改变它的表的背景,就可以这么更改:this.getParent().getParent().getParent().getStyle().backgroundColor = "Silver";
getValue
满足一些基于值变更视觉外观的需求。
if (this.getValue() > 30){
this.getStyle().fontFamily = "Arial"
this.getStyle().backgroundColor = "Yellow"
}
或者用这种方式也行:
if (this.getRowData().getExpressionValue("row[QtyOrdered]") > 30){
this.getStyle().fontFamily = "Arial"
this.getStyle().backgroundColor = "Yellow"
}
命名表达式
是指在某个元素上创建,并给予命名的表达式。其定义可在onPrepare中修改,其值可在onCreate和onRender中访问。例如,定义一个表达式totalCreditValue,其值为Total.sum(row[?CREDITLIMIT?])。然后,就可在其他元素中用JavaScript和Java访问。
例如,在某个表上建一个表达式"RWC",值为row[0],则可在行中用以下方式访问:
rc = this.parent.getNamedExpressionValue("RWC");
数据源事件:
beforeOpen |
数据源打开阶段,在连接数据源之前调用的脚本 |
afterOpen |
数据源打开之后的阶段调用的脚本 |
beforeClose |
在数据源关闭之前,可以调用的脚本 |
我们可以在数据源打开之前传入数据库密码,就是在beforeOpen中书写:
currentPassword = this.getExtensionProperty("odaPassword");
DataSourceClass = new Packages.myExternalSecurity();
this.setExtensionProperty("odaPassword", DataSourceClass.getPassword());
不过现在有了数据绑定,所以这种用法并不常见。
数据集事件:
beforeOpen |
数据集打开阶段,在连接数据源获取数据集之前调用的脚本 |
afterOpen |
数据集打开之后的阶段调用的脚本 |
fetch |
用于获取行数据阶段调用脚本 |
beforeClose |
在数据集关闭之前,可以调用的脚本 |
afterClose |
在数据集关闭之后,可以调用的脚本 |
如果是脚本数据源,那么在数据源上有open,close方法,数据集上还有open,fetch,close方法:
例如我们可以在beforeOpen中书写下面的脚本用来定制查询:
this.queryText = "SELECT * FROM Customers where CustomerID IN (" + params["customersInClause"] +")";
如果是脚本数据源,可以如下书写:
打开数据集阶段的事件open:
importPackage(Packages.test.my.ds)
myDataSet = new DS();
myArrayList = myDataSet.getList();
myIter = myArrayList.iterator();
获取数据集阶段fetch:
if( !myIter.hasNext() ){
return false;
}
//myOnlyColumn 必须已经在数据集中已经定义了
row["myOnlyColumn"] = iter.next();
return true;
我们可以在脚本中书写更复杂的逻辑,用来在运行时控制报表的显示。
例如在一个beforeOpen的方法中输入下面语句:
importPackage(Packages.org.eclipse.birt.report.model.api);
importPackage(Packages.org.eclipse.birt.report.model.api.elements);
delm = reportContext.getReportRunnable().designHandle.getDesignHandle().findElement("QTYELEMENT");
mr = StructureFactory.createMapRule();
mr.setTestExpression("row[\"QUANTITYORDERED\"]");
mr.setOperator(DesignChoiceConstants.MAP_OPERATOR_GT);
mr.setValue1("40");
mr.setDisplay("A lot");
ph = delm.getPropertyHandle(StyleHandle.MAP_RULES_PROP);
ph.addItem(mr);
说明,上面语句的含义是给报表添加一个映射MapRule,让行row["QUANTITYORDERED"]大于40的数据项都显示成"A lot"
预览如下:
我们还可以让它不显示HideRule:
- importPackage(Packages.org.eclipse.birt.report.model.api);
- importPackage(Packages.org.eclipse.birt.report.model.api.elements);
- delm = reportContext.getReportRunnable().designHandle.getDesignHandle().findElement("QTYELEMENT");
- hr = StructureFactory.createHideRule();
- hr.setFormat("html");
- hr.setExpression("if( row[\"QUANTITYORDERED\"] > 30 ){true;}else{false;}");
- ph = delm.getPropertyHandle("visibility");
- ph.addItem(hr);
预览效果如下:
也能动态增加排序字段:
- importPackage(Packages.org.eclipse.birt.report.model.api);
- importPackage(Packages.org.eclipse.birt.report.model.api.elements);
- delm = reportContext.getReportRunnable().designHandle.getDesignHandle().findElement("mytable");
- sc = StructureFactory.createSortKey();
- sc.setKey("row[\"CONTACTLASTNAME\"]");
- sc.setDirection("asc");
- ph = delm.getPropertyHandle(TableHandle.SORT_PROP);
- ph.addItem(sc);
下面的语句是给报表添加自动刷新和用户刷新,我们把它放置在任何onPrepare中即可:
- var paramsString = "";
- var paramDefs = reportContext.getDesignHandle().getAllParameters();
- for (i = 0; i < paramDefs.size(); i++ ) {
- var paramDef = paramDefs.get(i);
- if (paramDef.getClass().toString() == "class org.eclipse.birt.report.model.api.ScalarParameterHandle") {
- var paramVal = reportContext.getParameterValue(paramDef.getName())
- if (paramVal == null || paramVal == "null") {
- paramVal = "";
- } else if (paramVal.length > 0) {
- var paramValTmp = "";
- for (j = 0; j < paramVal.length; j++) {
- if (paramVal[j] != null && paramVal[j] != "null") {
- if (j > 0)
- paramValTmp += "|";
- paramValTmp += encodeURIComponent(paramVal[j]);
- }
- }
- paramVal = paramValTmp;
- } else {
- paramVal = encodeURIComponent(paramVal);
- }
- paramsString += "&" + paramDef.getName() + "=" + paramVal;
- }
- }
- this.content="<form name='input' onSubmit='return reloadPage();'>"
- +"<input type='submit' value='refresh report' onclick='reloadPage()'>refresh manual</input></form>"
- +"<script type=text/javascript'>"
- +"function reloadPage() {"
- //alert( targetURL );
- +" var targeturl = window.location+'"+paramsString+"';"
- +" location.replace(targeturl);"
- +" return false;"
- +"}"
- +"timer=setTimeout('reloadPage()', 20000);"
- +"</script>"
当然,图表也能书写脚本,如下所示:
- var chart1 = this.getReportElement( "Chart1" )
- var chart2 = this.getReportElement( "Chart2" )
- var chart3 = this.getReportElement( "Chart3" )
- var chart4 = this.getReportElement( "Chart4" )
- var chart5 = this.getReportElement( "Chart5" )
- var chart6 = this.getReportElement( "Chart6" )
- var chart7 = this.getReportElement( "Chart7" )
- var chart8 = this.getReportElement( "Chart8" )
- var chart9 = this.getReportElement( "Chart9" )
- var chart10 = this.getReportElement( "Chart10" )
- var chart11 = this.getReportElement( "Chart11" )
- var chart12 = this.getReportElement( "Chart12" )
- var chart13 = this.getReportElement( "Chart13" )
- var color1 = chart1.getTitle().getCaption().getColor()
- var color2 = chart2.getTitle().getCaption().getColor()
- var font = chart3.getTitle().getCaption().getFont()
- chart1.setColorByCategory( true );
- chart1.getTitle().getCaption().setValue( "Color by Category" );
- chart1.setColorByCategory( true );
- chart1.getTitle().getCaption().setValue( "Color by Category" );
- chart2.setColorByCategory( false );
- chart2.getTitle().getCaption().setValue( "Color by Value Series" );
- color1.setRed( 255 );
- color1.setGreen( 0 );
- color1.setBlue( 0 );
- chart1.getTitle().getCaption().setColor( color1 );
- chart2.setColorByCategory( false );
- chart2.getTitle().getCaption().setValue( "Color by Value Series" );
- color2.setRed(255);
- color2.setTransparency( 127 );
- chart3.getDescription().setValue("newDesc");
- chart3.getTitle().getCaption().setValue( chart3.getDescription().getValue() );
- font.setSize( 9 );
- font.setBold( false );
- font.setItalic( true );
- font.setStrikeThrough( true );
- font.setUnderline( true );