第十一章 BIRT数据绑定与脚本,事件机制详解

来源:互联网 发布:国外离线下载软件 编辑:程序博客网 时间:2024/06/05 22:31

11.1 事件机制详解

前面通过脚本获取数据源,以及在报表中利用单元格或者数据项的onRender方法添加脚本来增加交互性,或者直接在脚本编辑器中书写少量代码,或多或少的都利用到了BIRT的脚本和事件机制,但这仅仅只是冰山一角。

BIRT提供了一个基于Mozilla Rhino的脚本模型。报表引擎创建报表的过程可以划分为两个阶段——生成和呈现。生成阶段利用报表设计,生成一个名为报表文档的中间文件。呈现阶段利用报表文档进行渲染,生成HTMLPDF。报表生产线既可以将两个阶段作为一个任务执行,也可以作为两个任务分别执行。如果作为一个任务,那么报表文档是生成在内存中。在设计器中选择『以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;

}

把两个数据列拖入一个12列的表中,布局报表报表,做适当美化,预览效果如下:

为了查看这个报表的事件执行顺序,我们需要在报表,数据源,数据集,表,行,数据项上书写一系列日志,方法如下:

选择大纲视图,选择报表编辑器的脚本查看选项卡:

我们选中报表名称,在initialize中书写如下的语句:

// INTIALIZE THE LOGGER WITH A FILE BASED LOGGERimportPackage(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事件绑定

reportContextthis

在使用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也可用于访问会话级变量。

// attributeBeanBirt 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次,而onCreateonRender将调用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中修改,其值可在onCreateonRender中访问。例如,定义一个表达式totalCreditValue,其值为Total.sum(row[?CREDITLIMIT?])。然后,就可在其他元素中用JavaScriptJava访问。

例如,在某个表上建一个表达式"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

在数据集关闭之后,可以调用的脚本

如果是脚本数据源,那么在数据源上有openclose方法,数据集上还有openfetchclose方法:

例如我们可以在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 );chart4.setDimension( "ThreeDimensional" )chart5.setDimension( "TwoDimensional" )chart6.setDimension( "TwoDimensionalWithDepth" )chart7.setDimension( "TwoDimensional" )chart8.setDimension( "TwoDimensionalWithDepth" )chart9.setDimension( "ThreeDimensional" )chart10.getCategory().setSorting( "Descending" )chart10.getTitle().getCaption().setValue(chart10.getCategory( ).getOptionalValueGroupingExpr())chart11.getTitle().getCaption().setValue( chart11.getOutputType() )chart12.setOutputType("PNG")chart12.getTitle().getCaption().setValue( chart12.getOutputType() )chart13.getLegend( ).setVisible( true );chart13.getLegend( ).setShowValue( true );chart13.getLegend( ).getTitle( ).setVisible( true );chart13.getLegend( ).getTitle( ).getCaption( ).setValue( "Legend" )

说明,以上语句修改了13个图表,修改了分类颜色,标题,字体,排序等等

具体的使用说明,参考BIRT engine API