以下是一些在開發XMLP(BIP)報表的時候,開發RTF模版的一些技巧:
1、word表格
做RTF模版的時候,采用word中的表格來進行設計,下面的幾點很重要:
(1)標題行重復,可以實現新頁重復標題。
(2)嵌套表格、行列合並、邊框、底紋,可以實現特殊的布局。
(3)固定列寬、自動調整、禁止跨頁斷行,可以實現一些嚴格的布局控制。
2、行截斷與禁止折行
單據打印中對格式的要求比較高,如果某一行過長或者出現多次折行,就會破壞版面,尤其是套打等要求較高的場合,這里把各種方法作個小結。其實,這個地方更網頁開發很像,是否換行輸出就跟html中的word-wrap和word-break非常類似,可以參見《word-wrap和word-break的區別》,如果要設置超出顯示,也幾乎跟css中的overflow:hidden是一樣的。
(1)Word功能,不理想
固定列寬功能可以用,但固定行高不行,雖然設計時看到“固定”了,如果不加控制,運行后多出列寬的數據會自動折行。
(2)單行+截斷,即控制只有以一行,多余截斷,禁止折行。
在字段的后面,再加如下兩個命令:
<xsl:attribute xdofo:ctx="block" name="wrap-option">no-wrap</xsl:attribute>
<xsl:attribute xdofo:ctx="block" name="overflow">hidden</xsl:attribute>
(3)多行+截斷,難
如固定顯示3行,多余部分截斷,目前通過模版無法實現,只有在數據源中先將數據截至剛好3行的字符數,然后利用自動折行功能。這里還要注意空格,如果遇到空格,后面的單詞又顯示不下,將會提前自動折行。
3、條件格式化
在不同的條件下顯示不同的顏色、不同的列數、不同的標題、不同的布局風格等等,這些都屬於條件格式化,需要借助IF命令。
(1)比如不同幣種憑證打印格式不同:
<?if:CURRENCY_CODE="CNY"?>任何布局<?end if?>
<?if:CURRENCY_CODE!="CNY"?>任何布局<?end if?>
(2)比如貨幣為CNY時才顯示列,在目標列的單元格內寫如下語句:
<?if@column:CURRENCY_CODE="CNY"?>字段值和格式<?end if?>
注:這還不是真正的動態列。
(3)比如偶數行底色為灰色,在行的任何單元格內寫如下語句:
<?if@row:position() mod 2=0?>
<xsl:attribute xdofo:ctx="incontext" name="background-color">gray</xsl:attribute>
<?end if?>
<?if:position() mod 2=0?>
<xsl:attribute xdofo:ctx="incontext" name="background-color">gray</xsl:attribute>
<?end if?>
注意position()的意義,position()表示的是在XML數據源文件中,該條數據所處該組中全部數據中的位置,比如如果該組有10個明細行要顯示,當顯示到第三個明細行的時候,position()的值就是3。還有一個last(),該前面那個例子中,last()的值就是10,即最后一個明細行,有時候會用position()=last()來判斷是否已經把全部明細行都顯示了,非常有用。上面的那兩段代碼,加了@row則會使得該行全部變色,如果沒有加,就表示只對加了該段代碼的單元格變色。
(4)比如超過100單元格呈紅色,在目標單元格內寫如下語句:
<?if:QUANTITY>100?>
<xsl:attribute xdofo:ctx="block" name="background-color">red</xsl:attribute>
<?end if?>
4、字段計算建議做法
(1)計算字段可以先在SQL中完成。
(2)如果使用Oracle Reports做數據源,那么計算字段、統計字段也可以先完成。
(3)在SQL中的數據,都不帶格式,格式在模版中設置;需要在模版中完成計算的字段,必須不帶格式,主要指數字不能帶千位符號。
5、組內合計
N: Template Builder/插入/字段
向導可以完成基本的統計,目前支持分組內的:Sum、Count、Min、Max、Avarage。
自動生成的代碼示例:
<?sum (QUANTITY)?>
6、頁內合計
要實現本頁合計數,需分兩步:聲明合計變量、顯示合計變量(可帶格式)。
(1)對QUANTITY進行本頁合計,聲明變量QTYTOTAL,注意寫在QUANTITY對應的組內,不然引用不到。
<?add-page-total:QTYTOTAL;’QUANTITY’?>
(2)可在任意地方顯示合計數
<?show-page-total:QTYTOTAL?>
7、累計數
累計每行數字,實際上是這樣完成的:先聲明一個變量,初始化為0;累加;在需要的地方顯示累計。
(1)在分組標記前初始化,Set變量。
<?xdoxslt:set_variable($_XDOCTX,’RTotalVar’, 0)?>
(2)計算累計值,通常寫在欲累計的字段同一單元格內,比如下面的QUANTITY。
<?xdoxslt:set_variable($_XDOCTX, ‘RTotalVar’, xdoxslt:get_variable($_XDOCTX,’RTotalVar’) + QUANTITY)?>
(3)任意地方顯示累計值,Get變量。
<?xdoxslt:get_variable($_XDOCTX,’RTotalVar’)?>
8、新組分頁
下面幾種方式都可以實現新組分頁,下面的序號是表示方法,不是步驟:
(1)分組聲明中加@section,如下:
<?for-each@section:G_PO_HEADER?>
(2)<?end for-each?>前加<?split-by-page-break:?>。
(3)<?end for-each?>前加<xsl:attribute name="break-after">page</xsl:attribute>,此法下RTF最后無空白頁,但PDF有空白頁。
(4)<?end for-each?>前加<xsl:attribute name="break-before">page</xsl:attribute>此法下RTF、PDF最后都有空白頁。
見得比較多的是直接用(1)的方法。
9、條件分頁、固定行分頁
(1)任意條件分頁,需要借助IF + 上面的break-after或者break-before,如:
<?if:CURRENCY_CODE="CNY"?>
<xsl:attribute name="break-before">page</xsl:attribute>
<?end if?>
(2)固定行分頁,需要借助IF + 上面的break-after或者break-before,在行<?end for-each?>前,如下語句控制每頁5行:
<?if:position() mod 5 =0?>
<xsl:attribute name="break-before">page</xsl:attribute>
<?end if?>
10、頁眉頁腳
(1)標准的頁眉頁腳,即單個頁眉頁腳,使用Word的功能即可。
(2)擴展的頁眉頁腳,可使用<?start:body?><?end body?>把主體部分“框”起來,凡是在這兩個標記之外的東西,都將被當作頁眉頁腳。
11、頁碼和頁數
(1)可以利用word的功能,在任意地方插入頁碼,這個是“自然頁碼”。
(2)如果在某種情況下想讓頁碼從特定值開始,比如新組頁碼重新編號,則需要借助命令,如在for-each后寫:<?initial-page-number:1?>。這里的1,實際上也可以用數據文件中的XML元素來替換。
12、末頁、奇偶頁不同
(1)Word可在頁眉頁腳部分實現首頁不同或奇偶頁不同,沒法實現末頁不同,即使借助代碼控制,實際實現的也是末頁布局不同,而非“頁眉頁腳”不同。
<?start@last-page:body?><?end body?>
報表本身僅有一頁時,則用:
<?start@last-page-first:body?><?end body?>
注意布局需要獨立成頁,即之前需要加分頁符。
(2)以偶數頁結束,主要目的是顯示偶數頁頁眉頁腳。
<?section:force-page-count;’end-on-even-layout’?>
如果僅顯示空白頁,則用:
<?section:force-page-count;’end-on-even’?>
(3)以奇數頁結束,主要目的是顯示奇數頁頁眉頁腳。
如果僅顯示空白頁,則用:
<?section:force-page-count;’end-on-odd’?>
13、超鏈接
可以直接利用word功能設置超鏈接,也可以在鏈接地址中,全部或部分引用XML數據文件中的標記,做到動態超鏈接:
{SUPPLIER_SITE_URL}或者http://abcd.efg.com:8000/OA_MEDIA/{CURRENCY_CODE}.gif
14、圖片
可以直接利用Word功能插入圖片,也可以僅將該圖片當作占位圖,在圖片的“設置圖片格式”的網站標簽頁內的“可選文字”,可參考《word技巧:設置圖片格式》,輸入真正的圖片地址:
(1)來自網站的圖片:url:{'http://localhost:8000/OA_MEDIA/forms_logo.gif'}
(2)來自EBS的圖片:url:{'${OA_MEDIA}/forms_logo.gif'}
(3)動態指定地址:url:{IMAGE_URL}
(4)動態拼接的地址:url:{concat(SERVER,'/',IMAGE_DIR,'/',IMAGE_FILE)}
(5)直接來自內容為BLOB的XML元素,僅用於“Data Templates”:
<fo:instream-foreign-object content-type="image/jpg">
<xsl:value-of select="IMAGE_ELEMENT"/>
</fo:instram-foreign-object>
15、圖表
可使用Template Builder向導插入圖表,類型有:條形圖-垂直、條形圖-水平、餅圖、線形圖。向導生成的代碼,可在圖片的“設置圖片格式”網站標簽頁內的“可選文字”里看到,我們可以做進一步修改。
16、字段引用
在前面的窗體域中,我們直接引用XML文件中的Tag標記,如<?QUANTITY?>。這種對XML元素的引用,是相對當前層次的組來說;如果上層組中,有個同名Tag,就要通過類似“相對路徑”的方式引用,如<?../QUANTITY?>。這里的“../”個數,不是布局中的相對層測個數,而是XML數據文件中的相對層次!詳細可參見《Oracle BI Publiser報表開發中的路徑、層級問題》。
17、函數引用
(1)行號,准確講是分組中記錄順序號:<xsl:value-of select="position()"/>
(2)總行號:<xsl:value-of select="last()"/>
18、空值判斷
(1)有標記,值不為空
<?if:Element_Name!=""?>Something Here<?end if?>
(2)有標記,值為空
<?if:Element_Name and Element_Name=""?>Something Here<?end if?>
(3)無標記
<?if:not(Element_Name)?>Something Here<?end if?>
19、嵌套模版/子模版
嵌套模板是在模板中定義一個子模板,然后在需要的地方調用它,如在頁眉頁腳中調用它,這樣也可以突破頁眉和頁腳中不允許使用窗體域的限制。
(1)定義子模版
<?template:internaltemplate YOUR_TEMPLATE_NAME?>
……
<?end template?>
(2)調用子模版
<?call:internaltemplate YOUR_TEMPLATE_NAME?>
其他的一些技巧,以后在開發的過程中,遇到了再加入