第十一章 BIRT數據綁定與腳本,事件機制詳解

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中書寫如下的語句:

[javascript] view plaincopy
  1. // INTIALIZE THE LOGGER WITH A FILE BASED LOGGER  
  2.     importPackage(Packages.java.util.logging);  
  3.     importPackage(Packages.logging);  
  4.       
  5.     var fileHandler = new FileHandler("javascript.log"false);  
  6.     //fileHandler.setFormatter(new BirtEventFormatter());  
  7.       
  8.     var rootLogger = Logger.getLogger("");  
  9.     rootLogger.addHandler(fileHandler);  
  10.       
  11.   
  12.     function log ( str ){  
  13.         Logger.getAnonymousLogger().info(str);  
  14.     }  
  15.       
  16.     reportContext.setPersistentGlobalVariable("log", log);  
  17.     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文件:

內容如下:

  1. <?xml version="1.0" encoding="GBK" standalone="no"?>  
  2. <!DOCTYPE log SYSTEM "logger.dtd">  
  3. <log>  
  4. <record>  
  5.   <date>2013-01-05T10:43:00</date>  
  6.   <millis>1357353780241</millis>  
  7.   <sequence>170</sequence>  
  8.   <level>INFO</level>  
  9.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  10.   <method>invoke0</method>  
  11.   <thread>12</thread>  
  12.   <message>Initialize</message>  
  13. </record>  
  14. <record>  
  15.   <date>2013-01-05T10:43:00</date>  
  16.   <millis>1357353780241</millis>  
  17.   <sequence>171</sequence>  
  18.   <level>INFO</level>  
  19.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  20.   <method>invoke0</method>  
  21.   <thread>12</thread>  
  22.   <message>Table onPrepare</message>  
  23. </record>  
  24. <record>  
  25.   <date>2013-01-05T10:43:00</date>  
  26.   <millis>1357353780241</millis>  
  27.   <sequence>172</sequence>  
  28.   <level>INFO</level>  
  29.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  30.   <method>invoke0</method>  
  31.   <thread>12</thread>  
  32.   <message>Row onPrepare</message>  
  33. </record>  
  34. <record>  
  35.   <date>2013-01-05T10:43:00</date>  
  36.   <millis>1357353780241</millis>  
  37.   <sequence>173</sequence>  
  38.   <level>INFO</level>  
  39.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  40.   <method>invoke0</method>  
  41.   <thread>12</thread>  
  42.   <message>Cell onPrepare</message>  
  43. </record>  
  44. <record>  
  45.   <date>2013-01-05T10:43:00</date>  
  46.   <millis>1357353780241</millis>  
  47.   <sequence>174</sequence>  
  48.   <level>INFO</level>  
  49.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  50.   <method>invoke0</method>  
  51.   <thread>12</thread>  
  52.   <message>Data onPrepare</message>  
  53. </record>  
  54. <record>  
  55.   <date>2013-01-05T10:43:00</date>  
  56.   <millis>1357353780241</millis>  
  57.   <sequence>175</sequence>  
  58.   <level>INFO</level>  
  59.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  60.   <method>invoke0</method>  
  61.   <thread>12</thread>  
  62.   <message>before factory</message>  
  63. </record>  
  64. <record>  
  65.   <date>2013-01-05T10:43:00</date>  
  66.   <millis>1357353780241</millis>  
  67.   <sequence>176</sequence>  
  68.   <level>INFO</level>  
  69.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  70.   <method>invoke0</method>  
  71.   <thread>12</thread>  
  72.   <message>before render</message>  
  73. </record>  
  74. <record>  
  75.   <date>2013-01-05T10:43:00</date>  
  76.   <millis>1357353780256</millis>  
  77.   <sequence>177</sequence>  
  78.   <level>INFO</level>  
  79.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  80.   <method>invoke0</method>  
  81.   <thread>12</thread>  
  82.   <message>Data Source Before Open</message>  
  83. </record>  
  84. <record>  
  85.   <date>2013-01-05T10:43:00</date>  
  86.   <millis>1357353780256</millis>  
  87.   <sequence>178</sequence>  
  88.   <level>INFO</level>  
  89.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  90.   <method>invoke0</method>  
  91.   <thread>12</thread>  
  92.   <message>Data Source Open</message>  
  93. </record>  
  94. <record>  
  95.   <date>2013-01-05T10:43:00</date>  
  96.   <millis>1357353780256</millis>  
  97.   <sequence>179</sequence>  
  98.   <level>INFO</level>  
  99.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  100.   <method>invoke0</method>  
  101.   <thread>12</thread>  
  102.   <message>Data Source Afger Open</message>  
  103. </record>  
  104. <record>  
  105.   <date>2013-01-05T10:43:00</date>  
  106.   <millis>1357353780256</millis>  
  107.   <sequence>180</sequence>  
  108.   <level>INFO</level>  
  109.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  110.   <method>invoke0</method>  
  111.   <thread>12</thread>  
  112.   <message>Data Set BeforeOpen</message>  
  113. </record>  
  114. <record>  
  115.   <date>2013-01-05T10:43:00</date>  
  116.   <millis>1357353780256</millis>  
  117.   <sequence>181</sequence>  
  118.   <level>INFO</level>  
  119.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  120.   <method>invoke0</method>  
  121.   <thread>12</thread>  
  122.   <message>Data Set Open</message>  
  123. </record>  
  124. <record>  
  125.   <date>2013-01-05T10:43:00</date>  
  126.   <millis>1357353780256</millis>  
  127.   <sequence>182</sequence>  
  128.   <level>INFO</level>  
  129.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  130.   <method>invoke0</method>  
  131.   <thread>12</thread>  
  132.   <message>Data Set AfterOpen</message>  
  133. </record>  
  134. <record>  
  135.   <date>2013-01-05T10:43:00</date>  
  136.   <millis>1357353780256</millis>  
  137.   <sequence>183</sequence>  
  138.   <level>INFO</level>  
  139.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  140.   <method>invoke0</method>  
  141.   <thread>12</thread>  
  142.   <message>Data Set Fetch</message>  
  143. </record>  
  144. <record>  
  145.   <date>2013-01-05T10:43:00</date>  
  146.   <millis>1357353780256</millis>  
  147.   <sequence>184</sequence>  
  148.   <level>INFO</level>  
  149.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  150.   <method>invoke0</method>  
  151.   <thread>12</thread>  
  152.   <message>Data Set OnFetch</message>  
  153. </record>  
  154. <record>  
  155.   <date>2013-01-05T10:43:00</date>  
  156.   <millis>1357353780256</millis>  
  157.   <sequence>185</sequence>  
  158.   <level>INFO</level>  
  159.   <class>sun.reflect.NativeMethodAccessorImpl</class>  
  160.   <method>invoke0</method>  
  161.   <thread>12</thread>  
  162.   <message>Data Set Fetch</message>  
  163. </record>  
  164. <record>  
  165.   <date>2013-01-05T10:43:00</date>  
  166.   <millis>1357353780256</millis>  
  167.   <sequence>186</sequence>  
  168.   <level>INFO</level>  
  169.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  170.   <method>invoke</method>  
  171.   <thread>12</thread>  
  172.   <message>Data Set OnFetch</message>  
  173. </record>  
  174. <record>  
  175.   <date>2013-01-05T10:43:00</date>  
  176.   <millis>1357353780256</millis>  
  177.   <sequence>187</sequence>  
  178.   <level>INFO</level>  
  179.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  180.   <method>invoke</method>  
  181.   <thread>12</thread>  
  182.   <message>Data Set Fetch</message>  
  183. </record>  
  184. <record>  
  185.   <date>2013-01-05T10:43:00</date>  
  186.   <millis>1357353780256</millis>  
  187.   <sequence>188</sequence>  
  188.   <level>INFO</level>  
  189.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  190.   <method>invoke</method>  
  191.   <thread>12</thread>  
  192.   <message>Data Set OnFetch</message>  
  193. </record>  
  194. <record>  
  195.   <date>2013-01-05T10:43:00</date>  
  196.   <millis>1357353780256</millis>  
  197.   <sequence>189</sequence>  
  198.   <level>INFO</level>  
  199.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  200.   <method>invoke</method>  
  201.   <thread>12</thread>  
  202.   <message>Data Set Fetch</message>  
  203. </record>  
  204. <record>  
  205.   <date>2013-01-05T10:43:00</date>  
  206.   <millis>1357353780256</millis>  
  207.   <sequence>190</sequence>  
  208.   <level>INFO</level>  
  209.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  210.   <method>invoke</method>  
  211.   <thread>12</thread>  
  212.   <message>Data Set OnFetch</message>  
  213. </record>  
  214. <record>  
  215.   <date>2013-01-05T10:43:00</date>  
  216.   <millis>1357353780256</millis>  
  217.   <sequence>191</sequence>  
  218.   <level>INFO</level>  
  219.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  220.   <method>invoke</method>  
  221.   <thread>12</thread>  
  222.   <message>Data Set Fetch</message>  
  223. </record>  
  224. <record>  
  225.   <date>2013-01-05T10:43:00</date>  
  226.   <millis>1357353780256</millis>  
  227.   <sequence>192</sequence>  
  228.   <level>INFO</level>  
  229.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  230.   <method>invoke</method>  
  231.   <thread>12</thread>  
  232.   <message>Data Set OnFetch</message>  
  233. </record>  
  234. <record>  
  235.   <date>2013-01-05T10:43:00</date>  
  236.   <millis>1357353780256</millis>  
  237.   <sequence>193</sequence>  
  238.   <level>INFO</level>  
  239.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  240.   <method>invoke</method>  
  241.   <thread>12</thread>  
  242.   <message>Data Set Fetch</message>  
  243. </record>  
  244. <record>  
  245.   <date>2013-01-05T10:43:00</date>  
  246.   <millis>1357353780272</millis>  
  247.   <sequence>194</sequence>  
  248.   <level>INFO</level>  
  249.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  250.   <method>invoke</method>  
  251.   <thread>12</thread>  
  252.   <message>Table onCreate</message>  
  253. </record>  
  254. <record>  
  255.   <date>2013-01-05T10:43:00</date>  
  256.   <millis>1357353780272</millis>  
  257.   <sequence>195</sequence>  
  258.   <level>INFO</level>  
  259.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  260.   <method>invoke</method>  
  261.   <thread>12</thread>  
  262.   <message>Table onRender</message>  
  263. </record>  
  264. <record>  
  265.   <date>2013-01-05T10:43:00</date>  
  266.   <millis>1357353780272</millis>  
  267.   <sequence>196</sequence>  
  268.   <level>INFO</level>  
  269.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  270.   <method>invoke</method>  
  271.   <thread>12</thread>  
  272.   <message>Row onCreate</message>  
  273. </record>  
  274. <record>  
  275.   <date>2013-01-05T10:43:00</date>  
  276.   <millis>1357353780272</millis>  
  277.   <sequence>197</sequence>  
  278.   <level>INFO</level>  
  279.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  280.   <method>invoke</method>  
  281.   <thread>12</thread>  
  282.   <message>Row onRender</message>  
  283. </record>  
  284. <record>  
  285.   <date>2013-01-05T10:43:00</date>  
  286.   <millis>1357353780272</millis>  
  287.   <sequence>198</sequence>  
  288.   <level>INFO</level>  
  289.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  290.   <method>invoke</method>  
  291.   <thread>12</thread>  
  292.   <message>Row onCreate</message>  
  293. </record>  
  294. <record>  
  295.   <date>2013-01-05T10:43:00</date>  
  296.   <millis>1357353780272</millis>  
  297.   <sequence>199</sequence>  
  298.   <level>INFO</level>  
  299.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  300.   <method>invoke</method>  
  301.   <thread>12</thread>  
  302.   <message>Row onRender</message>  
  303. </record>  
  304. <record>  
  305.   <date>2013-01-05T10:43:00</date>  
  306.   <millis>1357353780272</millis>  
  307.   <sequence>200</sequence>  
  308.   <level>INFO</level>  
  309.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  310.   <method>invoke</method>  
  311.   <thread>12</thread>  
  312.   <message>Row onCreate</message>  
  313. </record>  
  314. <record>  
  315.   <date>2013-01-05T10:43:00</date>  
  316.   <millis>1357353780272</millis>  
  317.   <sequence>201</sequence>  
  318.   <level>INFO</level>  
  319.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  320.   <method>invoke</method>  
  321.   <thread>12</thread>  
  322.   <message>Row onRender</message>  
  323. </record>  
  324. <record>  
  325.   <date>2013-01-05T10:43:00</date>  
  326.   <millis>1357353780272</millis>  
  327.   <sequence>202</sequence>  
  328.   <level>INFO</level>  
  329.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  330.   <method>invoke</method>  
  331.   <thread>12</thread>  
  332.   <message>Row onCreate</message>  
  333. </record>  
  334. <record>  
  335.   <date>2013-01-05T10:43:00</date>  
  336.   <millis>1357353780272</millis>  
  337.   <sequence>203</sequence>  
  338.   <level>INFO</level>  
  339.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  340.   <method>invoke</method>  
  341.   <thread>12</thread>  
  342.   <message>Row onRender</message>  
  343. </record>  
  344. <record>  
  345.   <date>2013-01-05T10:43:00</date>  
  346.   <millis>1357353780272</millis>  
  347.   <sequence>204</sequence>  
  348.   <level>INFO</level>  
  349.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  350.   <method>invoke</method>  
  351.   <thread>12</thread>  
  352.   <message>Row onCreate</message>  
  353. </record>  
  354. <record>  
  355.   <date>2013-01-05T10:43:00</date>  
  356.   <millis>1357353780272</millis>  
  357.   <sequence>205</sequence>  
  358.   <level>INFO</level>  
  359.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  360.   <method>invoke</method>  
  361.   <thread>12</thread>  
  362.   <message>Row onRender</message>  
  363. </record>  
  364. <record>  
  365.   <date>2013-01-05T10:43:00</date>  
  366.   <millis>1357353780272</millis>  
  367.   <sequence>206</sequence>  
  368.   <level>INFO</level>  
  369.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  370.   <method>invoke</method>  
  371.   <thread>12</thread>  
  372.   <message>Row onCreate</message>  
  373. </record>  
  374. <record>  
  375.   <date>2013-01-05T10:43:00</date>  
  376.   <millis>1357353780272</millis>  
  377.   <sequence>207</sequence>  
  378.   <level>INFO</level>  
  379.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  380.   <method>invoke</method>  
  381.   <thread>12</thread>  
  382.   <message>Row onRender</message>  
  383. </record>  
  384. <record>  
  385.   <date>2013-01-05T10:43:00</date>  
  386.   <millis>1357353780272</millis>  
  387.   <sequence>208</sequence>  
  388.   <level>INFO</level>  
  389.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  390.   <method>invoke</method>  
  391.   <thread>12</thread>  
  392.   <message>Row onCreate</message>  
  393. </record>  
  394. <record>  
  395.   <date>2013-01-05T10:43:00</date>  
  396.   <millis>1357353780272</millis>  
  397.   <sequence>209</sequence>  
  398.   <level>INFO</level>  
  399.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  400.   <method>invoke</method>  
  401.   <thread>12</thread>  
  402.   <message>Row onRender</message>  
  403. </record>  
  404. <record>  
  405.   <date>2013-01-05T10:43:00</date>  
  406.   <millis>1357353780272</millis>  
  407.   <sequence>210</sequence>  
  408.   <level>INFO</level>  
  409.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  410.   <method>invoke</method>  
  411.   <thread>12</thread>  
  412.   <message>Row onCreate</message>  
  413. </record>  
  414. <record>  
  415.   <date>2013-01-05T10:43:00</date>  
  416.   <millis>1357353780272</millis>  
  417.   <sequence>211</sequence>  
  418.   <level>INFO</level>  
  419.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  420.   <method>invoke</method>  
  421.   <thread>12</thread>  
  422.   <message>Row onRender</message>  
  423. </record>  
  424. <record>  
  425.   <date>2013-01-05T10:43:00</date>  
  426.   <millis>1357353780272</millis>  
  427.   <sequence>212</sequence>  
  428.   <level>INFO</level>  
  429.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  430.   <method>invoke</method>  
  431.   <thread>12</thread>  
  432.   <message>Row onCreate</message>  
  433. </record>  
  434. <record>  
  435.   <date>2013-01-05T10:43:00</date>  
  436.   <millis>1357353780272</millis>  
  437.   <sequence>213</sequence>  
  438.   <level>INFO</level>  
  439.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  440.   <method>invoke</method>  
  441.   <thread>12</thread>  
  442.   <message>Row onRender</message>  
  443. </record>  
  444. <record>  
  445.   <date>2013-01-05T10:43:00</date>  
  446.   <millis>1357353780272</millis>  
  447.   <sequence>214</sequence>  
  448.   <level>INFO</level>  
  449.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  450.   <method>invoke</method>  
  451.   <thread>12</thread>  
  452.   <message>Row onCreate</message>  
  453. </record>  
  454. <record>  
  455.   <date>2013-01-05T10:43:00</date>  
  456.   <millis>1357353780272</millis>  
  457.   <sequence>215</sequence>  
  458.   <level>INFO</level>  
  459.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  460.   <method>invoke</method>  
  461.   <thread>12</thread>  
  462.   <message>Row onRender</message>  
  463. </record>  
  464. <record>  
  465.   <date>2013-01-05T10:43:00</date>  
  466.   <millis>1357353780272</millis>  
  467.   <sequence>216</sequence>  
  468.   <level>INFO</level>  
  469.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  470.   <method>invoke</method>  
  471.   <thread>12</thread>  
  472.   <message>Row onCreate</message>  
  473. </record>  
  474. <record>  
  475.   <date>2013-01-05T10:43:00</date>  
  476.   <millis>1357353780272</millis>  
  477.   <sequence>217</sequence>  
  478.   <level>INFO</level>  
  479.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  480.   <method>invoke</method>  
  481.   <thread>12</thread>  
  482.   <message>Row onRender</message>  
  483. </record>  
  484. <record>  
  485.   <date>2013-01-05T10:43:00</date>  
  486.   <millis>1357353780272</millis>  
  487.   <sequence>218</sequence>  
  488.   <level>INFO</level>  
  489.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  490.   <method>invoke</method>  
  491.   <thread>12</thread>  
  492.   <message>Row onCreate</message>  
  493. </record>  
  494. <record>  
  495.   <date>2013-01-05T10:43:00</date>  
  496.   <millis>1357353780272</millis>  
  497.   <sequence>219</sequence>  
  498.   <level>INFO</level>  
  499.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  500.   <method>invoke</method>  
  501.   <thread>12</thread>  
  502.   <message>Row onRender</message>  
  503. </record>  
  504. <record>  
  505.   <date>2013-01-05T10:43:00</date>  
  506.   <millis>1357353780272</millis>  
  507.   <sequence>220</sequence>  
  508.   <level>INFO</level>  
  509.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  510.   <method>invoke</method>  
  511.   <thread>12</thread>  
  512.   <message>Row onCreate</message>  
  513. </record>  
  514. <record>  
  515.   <date>2013-01-05T10:43:00</date>  
  516.   <millis>1357353780272</millis>  
  517.   <sequence>221</sequence>  
  518.   <level>INFO</level>  
  519.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  520.   <method>invoke</method>  
  521.   <thread>12</thread>  
  522.   <message>Row onRender</message>  
  523. </record>  
  524. <record>  
  525.   <date>2013-01-05T10:43:00</date>  
  526.   <millis>1357353780272</millis>  
  527.   <sequence>222</sequence>  
  528.   <level>INFO</level>  
  529.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  530.   <method>invoke</method>  
  531.   <thread>12</thread>  
  532.   <message>Row onCreate</message>  
  533. </record>  
  534. <record>  
  535.   <date>2013-01-05T10:43:00</date>  
  536.   <millis>1357353780272</millis>  
  537.   <sequence>223</sequence>  
  538.   <level>INFO</level>  
  539.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  540.   <method>invoke</method>  
  541.   <thread>12</thread>  
  542.   <message>Row onRender</message>  
  543. </record>  
  544. <record>  
  545.   <date>2013-01-05T10:43:00</date>  
  546.   <millis>1357353780272</millis>  
  547.   <sequence>224</sequence>  
  548.   <level>INFO</level>  
  549.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  550.   <method>invoke</method>  
  551.   <thread>12</thread>  
  552.   <message>Row onCreate</message>  
  553. </record>  
  554. <record>  
  555.   <date>2013-01-05T10:43:00</date>  
  556.   <millis>1357353780272</millis>  
  557.   <sequence>225</sequence>  
  558.   <level>INFO</level>  
  559.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  560.   <method>invoke</method>  
  561.   <thread>12</thread>  
  562.   <message>Row onRender</message>  
  563. </record>  
  564. <record>  
  565.   <date>2013-01-05T10:43:00</date>  
  566.   <millis>1357353780272</millis>  
  567.   <sequence>226</sequence>  
  568.   <level>INFO</level>  
  569.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  570.   <method>invoke</method>  
  571.   <thread>12</thread>  
  572.   <message>Data Set BeforeClose</message>  
  573. </record>  
  574. <record>  
  575.   <date>2013-01-05T10:43:00</date>  
  576.   <millis>1357353780272</millis>  
  577.   <sequence>227</sequence>  
  578.   <level>INFO</level>  
  579.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  580.   <method>invoke</method>  
  581.   <thread>12</thread>  
  582.   <message>Data Set Close</message>  
  583. </record>  
  584. <record>  
  585.   <date>2013-01-05T10:43:00</date>  
  586.   <millis>1357353780272</millis>  
  587.   <sequence>228</sequence>  
  588.   <level>INFO</level>  
  589.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  590.   <method>invoke</method>  
  591.   <thread>12</thread>  
  592.   <message>Data Set AfterOpen</message>  
  593. </record>  
  594. <record>  
  595.   <date>2013-01-05T10:43:00</date>  
  596.   <millis>1357353780288</millis>  
  597.   <sequence>229</sequence>  
  598.   <level>INFO</level>  
  599.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  600.   <method>invoke</method>  
  601.   <thread>12</thread>  
  602.   <message>Table onPageBreak</message>  
  603. </record>  
  604. <record>  
  605.   <date>2013-01-05T10:43:00</date>  
  606.   <millis>1357353780288</millis>  
  607.   <sequence>230</sequence>  
  608.   <level>INFO</level>  
  609.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  610.   <method>invoke</method>  
  611.   <thread>12</thread>  
  612.   <message>Row onPageBreak</message>  
  613. </record>  
  614. <record>  
  615.   <date>2013-01-05T10:43:00</date>  
  616.   <millis>1357353780288</millis>  
  617.   <sequence>231</sequence>  
  618.   <level>INFO</level>  
  619.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  620.   <method>invoke</method>  
  621.   <thread>12</thread>  
  622.   <message>Row onPageBreak</message>  
  623. </record>  
  624. <record>  
  625.   <date>2013-01-05T10:43:00</date>  
  626.   <millis>1357353780288</millis>  
  627.   <sequence>232</sequence>  
  628.   <level>INFO</level>  
  629.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  630.   <method>invoke</method>  
  631.   <thread>12</thread>  
  632.   <message>Row onPageBreak</message>  
  633. </record>  
  634. <record>  
  635.   <date>2013-01-05T10:43:00</date>  
  636.   <millis>1357353780288</millis>  
  637.   <sequence>233</sequence>  
  638.   <level>INFO</level>  
  639.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  640.   <method>invoke</method>  
  641.   <thread>12</thread>  
  642.   <message>Row onPageBreak</message>  
  643. </record>  
  644. <record>  
  645.   <date>2013-01-05T10:43:00</date>  
  646.   <millis>1357353780288</millis>  
  647.   <sequence>234</sequence>  
  648.   <level>INFO</level>  
  649.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  650.   <method>invoke</method>  
  651.   <thread>12</thread>  
  652.   <message>Row onPageBreak</message>  
  653. </record>  
  654. <record>  
  655.   <date>2013-01-05T10:43:00</date>  
  656.   <millis>1357353780288</millis>  
  657.   <sequence>235</sequence>  
  658.   <level>INFO</level>  
  659.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  660.   <method>invoke</method>  
  661.   <thread>12</thread>  
  662.   <message>after render</message>  
  663. </record>  
  664. <record>  
  665.   <date>2013-01-05T10:43:00</date>  
  666.   <millis>1357353780288</millis>  
  667.   <sequence>236</sequence>  
  668.   <level>INFO</level>  
  669.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  670.   <method>invoke</method>  
  671.   <thread>12</thread>  
  672.   <message>Data Source Before Close</message>  
  673. </record>  
  674. <record>  
  675.   <date>2013-01-05T10:43:00</date>  
  676.   <millis>1357353780288</millis>  
  677.   <sequence>237</sequence>  
  678.   <level>INFO</level>  
  679.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  680.   <method>invoke</method>  
  681.   <thread>12</thread>  
  682.   <message>Data Source Close</message>  
  683. </record>  
  684. <record>  
  685.   <date>2013-01-05T10:43:00</date>  
  686.   <millis>1357353780288</millis>  
  687.   <sequence>238</sequence>  
  688.   <level>INFO</level>  
  689.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  690.   <method>invoke</method>  
  691.   <thread>12</thread>  
  692.   <message>Data Source After Close</message>  
  693. </record>  
  694. <record>  
  695.   <date>2013-01-05T10:43:00</date>  
  696.   <millis>1357353780288</millis>  
  697.   <sequence>239</sequence>  
  698.   <level>INFO</level>  
  699.   <class>sun.reflect.GeneratedMethodAccessor24</class>  
  700.   <method>invoke</method>  
  701.   <thread>12</thread>  
  702.   <message>after factory</message>  
  703. </record>  
  704. </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()

如,圖表標題可以這樣修改:

[javascript] view plaincopy
  1. function beforeGeneration(chart, context){  
  2.   
  3. importPackage(Packages.org.eclipse.birt.chart.model.type.impl);  
  4.   
  5. newChartTitle = context.getExternalContext().getScriptable().getPersistentGlobalVariable("testglobal");  
  6.   
  7. chart.getTitle().getLabel().getCaption().setValue(newChartTitle);  
  8.   
  9. }  

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") // 對該行套用表達式的值

例如:

[javascript] view plaincopy
  1. if (this.getRowData().getExpressionValue(1) == "product1")  
  2.   
  3. this.getStyle().backgroundColor = "red";  
  4.   
  5. if (this.getRowData().getExpressionValue("row[price]" == "$30")  
  6.   
  7. 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

[javascript] view plaincopy
  1. importPackage(Packages.org.eclipse.birt.report.model.api);  
  2.   
  3. importPackage(Packages.org.eclipse.birt.report.model.api.elements);  
  4.   
  5.   
  6. delm = reportContext.getReportRunnable().designHandle.getDesignHandle().findElement("QTYELEMENT");  
  7.   
  8. hr = StructureFactory.createHideRule();  
  9.   
  10. hr.setFormat("html");  
  11.   
  12. hr.setExpression("if( row[\"QUANTITYORDERED\"] > 30 ){true;}else{false;}");  
  13.   
  14. ph = delm.getPropertyHandle("visibility");  
  15.   
  16. ph.addItem(hr);  

預覽效果如下:

也能動態增加排序字段:

[javascript] view plaincopy
  1. importPackage(Packages.org.eclipse.birt.report.model.api);  
  2. importPackage(Packages.org.eclipse.birt.report.model.api.elements);  
  3.   
  4. delm = reportContext.getReportRunnable().designHandle.getDesignHandle().findElement("mytable");  
  5. sc = StructureFactory.createSortKey();  
  6. sc.setKey("row[\"CONTACTLASTNAME\"]");  
  7. sc.setDirection("asc");  
  8. ph = delm.getPropertyHandle(TableHandle.SORT_PROP);  
  9. ph.addItem(sc);  

下面的語句是給報表添加自動刷新和用戶刷新,我們把它放置在任何onPrepare中即可:

[javascript] view plaincopy
  1. var paramsString = "";  
  2. var paramDefs = reportContext.getDesignHandle().getAllParameters();  
  3. for (i = 0; i < paramDefs.size(); i++ ) {  
  4.     var paramDef = paramDefs.get(i);  
  5.     if (paramDef.getClass().toString() == "class org.eclipse.birt.report.model.api.ScalarParameterHandle") {  
  6.         var paramVal = reportContext.getParameterValue(paramDef.getName())        
  7.         if (paramVal == null || paramVal == "null") {  
  8.             paramVal = "";  
  9.         } else if (paramVal.length > 0) {  
  10.             var paramValTmp = "";  
  11.             for (j = 0; j < paramVal.length; j++) {  
  12.                 if (paramVal[j] != null && paramVal[j] != "null") {  
  13.                     if (j > 0)  
  14.                         paramValTmp += "|";  
  15.                     paramValTmp += encodeURIComponent(paramVal[j]);  
  16.                 }  
  17.             }  
  18.             paramVal = paramValTmp;  
  19.         } else {  
  20.             paramVal = encodeURIComponent(paramVal);  
  21.         }                     
  22.         paramsString += "&" + paramDef.getName() + "=" + paramVal;  
  23.     }  
  24. }  
  25.   
  26. this.content="<form name='input' onSubmit='return reloadPage();'>"  
  27. +"<input type='submit' value='refresh report' οnclick='reloadPage()'>refresh manual</input></form>"  
  28. +"<script type=text/javascript'>"  
  29. +"function reloadPage() {"  
  30.     //alert( targetURL );     
  31. +"    var targeturl = window.location+'"+paramsString+"';"  
  32. +"    location.replace(targeturl);"  
  33. +"    return false;"  
  34. +"}"  
  35. +"timer=setTimeout('reloadPage()', 20000);"  
  36. +"</script>"  

當然,圖表也能書寫腳本,如下所示:

[javascript] view plaincopy
  1. var chart1 = this.getReportElement( "Chart1" )  
  2. var chart2 = this.getReportElement( "Chart2" )  
  3. var chart3 = this.getReportElement( "Chart3" )  
  4. var chart4 = this.getReportElement( "Chart4" )  
  5. var chart5 = this.getReportElement( "Chart5" )  
  6. var chart6 = this.getReportElement( "Chart6" )  
  7. var chart7 = this.getReportElement( "Chart7" )  
  8.   
  9. var chart8 = this.getReportElement( "Chart8" )  
  10. var chart9 = this.getReportElement( "Chart9" )  
  11. var chart10 = this.getReportElement( "Chart10" )  
  12. var chart11 = this.getReportElement( "Chart11" )  
  13. var chart12 = this.getReportElement( "Chart12" )  
  14. var chart13 = this.getReportElement( "Chart13" )  
  15.   
  16. var color1 = chart1.getTitle().getCaption().getColor()  
  17. var color2 = chart2.getTitle().getCaption().getColor()  
  18. var font = chart3.getTitle().getCaption().getFont()  
  19.   
  20. chart1.setColorByCategory( true );  
  21. chart1.getTitle().getCaption().setValue( "Color by Category" );  
  22. chart1.setColorByCategory( true );  
  23. chart1.getTitle().getCaption().setValue( "Color by Category" );  
  24. chart2.setColorByCategory( false );  
  25. chart2.getTitle().getCaption().setValue( "Color by Value Series" );  
  26. color1.setRed( 255 );  
  27. color1.setGreen( 0 );  
  28. color1.setBlue( 0 );  
  29. chart1.getTitle().getCaption().setColor( color1 );  
  30. chart2.setColorByCategory( false );  
  31. chart2.getTitle().getCaption().setValue( "Color by Value Series" );  
  32. color2.setRed(255);  
  33. color2.setTransparency( 127 );  
  34.   
  35. chart3.getDescription().setValue("newDesc");  
  36. chart3.getTitle().getCaption().setValue( chart3.getDescription().getValue() );  
  37. font.setSize( 9 );  
  38. font.setBold( false );  
  39. font.setItalic( true );  
  40. font.setStrikeThrough( true );  
  41. font.setUnderline( true );  
  42.   
  43. chart4.setDimension( "ThreeDimensional" )  
  44. chart5.setDimension( "TwoDimensional" )  
  45. chart6.setDimension( "TwoDimensionalWithDepth" )  
  46. chart7.setDimension( "TwoDimensional" )  
  47. chart8.setDimension( "TwoDimensionalWithDepth" )  
  48. chart9.setDimension( "ThreeDimensional" )  
  49.   
  50. chart10.getCategory().setSorting( "Descending" )  
  51. chart10.getTitle().getCaption().setValue(chart10.getCategory( ).getOptionalValueGroupingExpr())  
  52.   
  53. chart11.getTitle().getCaption().setValue( chart11.getOutputType() )  
  54. chart12.setOutputType("PNG")  
  55. chart12.getTitle().getCaption().setValue( chart12.getOutputType() )  
  56.   
  57. chart13.getLegend( ).setVisible( true );  
  58. chart13.getLegend( ).setShowValue( true );  
  59. chart13.getLegend( ).getTitle( ).setVisible( true );  
  60. chart13.getLegend( ).getTitle( ).getCaption( ).setValue( "Legend" )  

說明,以上語句修改了13個圖表,修改了分類顏色,標題,字體,排序等等

具體的使用說明,參考BIRT engine API

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章