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' οnclick='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: