本文包含了Microsoft® SQL Server™報表格服務報表設計的技巧和最佳實務。本文提供一些基本的設計問題和一些報表格服務的功能。
關於這篇文檔
從使用資料控制項,到使用什麼格式,到如何分發報表,報表製作者面對著很多種選擇。Microsoft® SQL Server™ 報表格服務提供了豐富的報表設計和格式的支援,從基於紙介質表格報表到帶有圖片和切入功能的互動式報表
這篇文檔包括了報表製作和設計中的指導、建議和技巧。本文檔的目的在於解釋一般性的問題並對初學者提供指導建議。報表格服務聯機叢書提供了報表的製作和設計的豐富資源,並且詳細的描述了報表的設定和可用功能及參數。
本文適用於初學者和有一些經驗的報表製作者。報表製作的初學者也可以從報表設計章節中得到協助。
其他資訊來源
本文不包含全部的報表格服務的資訊。如果希望擷取詳細的產品資訊,請查看產品文檔和在http://www.microsoft.com/sql/reporting/ 中可用的線上資源。
產品版本
雖然本文基於Microsoft t® SQL Server™ 2005報表格服務,報表設計的相關資訊也適用於早期版本的報表格服務。
簡介
Microsoft® SQL Server™ 報表格服務是一種完整的報表工具。在使用報表格服務中,你可以設計和發布多種樣式的報表,從簡單表格到帶有圖形和互動式串連的線上自由表單。報表格服務可以將報表渲染成使用者指定的多種格式,包括HTML、PDF、Excel和映像格式。
對於各種設定和選擇對於報表製作者在選擇報表布局是需要解決的問題。這篇文章提供了一些指導方針是使用者在做選擇是更加容易並解答了一些常見的問題。
製作工具和RDL
報表格服務提供了多種製作報表的方法。SQL Server 和Microsoft® Visual Studio® 2005 都包括了圖形化的報表設計工具。SQL Server 2005報表格服務提供了Report Builder工具協助業務人員設計報表。也有其他的開發工具可以建立報表格服務的報表格式。
無論我們使用哪一種製作環境,所有的報表定義都是用報表定義語言(RDL)格式儲存,RDL是一種公開的XML定義報表的格式。這樣可以直接編寫RDL或者建立自訂工具產生相應格式。報表製作者可以使用圖形化的製作工具編輯已存在的RDL檔案。
在範例中展示特殊的技術時,文章提取了實現該功能的部分RDL。
在報表格服務的網站上http://www.microsoft.com/sql/reporting/可以擷取完整的RDL規範。
報表設計概念
本節描述了影響報表設計和布局的關鍵因素。如果你是剛剛接觸報表格服務,這裡的內容會對你有協助。所有的這些話題在SQL Server 聯機叢書中都有詳盡的描述。
在設計報表格服務中的報表時,你定義了資料並制定在頁面上的排列。儘管這個過程聽起來很基礎,報表格服務還是提供了下列特性:
◆支援4種不同的資料區域:列表,表格,矩陣和圖表。
◆提供了例如文字框,圖片,串連,矩形和子報表等一些列控制項。
◆使用者可以通過參數,條件過濾,使用者端排序,切入和文件引導模式來實現互動功能。
◆報表可以被渲染成各種格式,包括HTML,Excel,PDF,映像,XML和逗號分隔字元 (CSV) 。
你做的關於每一個關鍵地區的決策都會影響最重的顯示效果和報表功能。接下來的章節將提供影響設計和布局效果的因素。
資料區域
在我們的報表中我們第一個選擇就是選擇資料區域類型。報表格服務提供了下列資料區域類型:
◆表格
表格通過一行接一行的方式表現資料。列是固定的你無法擴充,但是行可以向下展開。因此,當表格增長時,它將資料向下展開。你也可以在表格內將資料分組。
◆矩陣
A矩陣或者叫交叉表類似於表格,但是行和列都是可以擴充並填充資料的。矩陣可以向外和向下增加其他報表對象。你可以在矩陣中在行和列中嵌套分組。
◆列表
列表適用於建立表單的自由表單資料區域。你可以通過嵌套列表來分組資料。
◆圖表
圖表是資料的圖形表達方式。報表格服務提供了多種圖表的格式。
你選擇的資料區域可能依賴於你使用的資料類型、你希望報表的外觀和如何展現報表。例如,要以Microsoft® Excel®形式呈遞的報表使用表格比使用列表更適合。
報表專案的位置和尺寸
報表有3個主要的地區組成:頁首,頁尾和本文。報表格服務支援將報表中任意放置報表專案。資料區域可以和其它地區並行或通過分組來嵌套。
當設計報表時,理解當報表專案增長時如何處理是非常重要的。報表專案可以水平或垂直的增長,依賴於重複的片斷,內容的尺寸和諸如字型等報表渲染的因素。
當報表專案增長時,例如一個表格,它會產生很多相關的報表專案。這些報表專案會在同一個父容器中。有如下2種方法來控制報表專案的移動:
◆每個報表專案為了維護與上邊報表專案間的最小距離會向下移動。
◆每個報表專案為了維護與左側報表專案間的最小距離會向右移動。
如果一個報表專案增長,它會擴充包含它的容器的邊界,容器會適應所包容的報表專案變化尺寸。
如果報表專案和其他的報表專案重疊,報表定義中的ZIndex元素決定哪個元素在頂層。ZIndex值高的報表專案會置於上層。
這些是一些你可以用來控制報表專案的增長和移動方法的技術。如果需要使用矩形和報表專案的分組的資訊,請參考本文後面“實用的報表設計技巧”部分。
分頁
對於場報表來說關鍵問題在於如何控制頁面的分割。頁面通過2個因素控制分割:
◆頁面尺寸
◆使用者指定對象前後頁面分割
頁面尺寸
為了控制頁面的尺寸,可以通過下列指導設定頁面的高度和寬度屬性:
◆可以通過報表的PageHeight和PageWidth屬性設定渲染後的物理頁面格式。
◆例如HTML這樣的互動式渲染格式不能渲染物理頁面分割。而使用 InteractiveHeight 和 InteractiveWidth 屬性建立邏輯的頁面分割。
◆有一些渲染格式,例如Excel,不支援頁面尺寸。對於這些報表,你將不得不使用頁面分割符將報表分割成多個頁面。
注意,如果報表的自身寬度比頁面寬度大,報表將在水平方向上交叉於多個頁面。
頁面分割
你可以在矩形,表格,矩陣,列表,圖表和分組中的開始或結尾處添加分頁符。報表格服務會嘗試將所有報表專案和資料分組保持在同一個頁面上。
可以使用報表專案中的PageBreakAtEnd和PageBreakAtStart屬性指定在報表專案之前或之後插入分頁符。
子報表
子報表是在報表專案中指向另外一個報表。任何報表可以被用於一個子報表,並且你可以設定父報表將要傳遞到子報表的參數。
但是用子報表時你要注意下列前提:
◆子報表無法和父報表共用資料。報表伺服器為分割的報表處理每一個子報表執行個體,但是這會影響效能。
◆子報表的頁首和頁尾會被忽略。
子報表在下列環境中十分有用:
◆當你需要在一個資料區域中從不同資料來源嵌套分組。
◆當報表有多個一對多關聯性的部分。
◆當你需要在多個父報表中重用子報表。
◆當你需要在其他報表內部嵌入一個標準的,獨立的報表。
如果報表共用資料,類似表格,矩陣,列表和圖表這樣的資料區域提供了與子報表同樣的功能。然而,它們提供更好的效能。資料區域在並行的布局中提供了比子報表更好的工作方式。
運算式和函數
報表製作者可以在報表中使用運算式資料的外觀,更改報表專案的屬性或控制資料的擷取。本文的技巧章節提供了一些使用運算式的設計範例。
你可以在運算式中使用Microsoft® Visual Basic®函數。在表1中顯示了一些常用的函數。
表1
Visual Basic 函數 |
結果 |
| Today() |
返回當前日期。 |
| DateAdd() |
基於單一參數提供一段日期。 |
| Year() |
顯示指定日期中的年份。使用它分組日期或做為一系列日期的標籤。 |
| Month() |
顯示日期中的月份 |
| Format() |
格式化字串。可以用于格式化日起和數字。 |
| Right(), Left(), and InStr() |
返回截取後字串中的一部分。 |
| Iif |
依照評估的運算式,返回2個值中的1個。為了返回3個值中的1個,你可以嵌套Iif函數。 |
你可以通過引用適當的裝配件在運算式中使用.NET函數。你也可以使用自訂的裝配件。如果需要此方面更詳細的資訊,請查看報表格服務聯機叢書中”Using Customer Assemblies with Reports”部分。
彙總函式和範圍
報表格服務提供了許多彙總函式可以在報表中建立總和或其他彙總。
每個彙總函數支援一個定義匯總範圍的範圍參數。範圍可以通過分組名稱,資料集或資料區域來指定。資料區域或分組必須直接或間接包含彙總函式指定的報表專案。
如果你忽略了範圍,彙總範圍是報表專案所在的分組或資料區域中最裡面的分組。
表2中顯示了報表格服務支援的彙總函式:
表2
函數 |
描述 |
Avg |
從指定運算式中返回所有非空值的平均值。 |
Count |
返回指定運算式中值的數量。 |
CountDistinct |
返回指定運算式中所有不同值的數量。 |
CountRows |
返回指定範圍中行的數量。 |
First |
從指定運算式中返回第一個值。 |
Last |
從指定運算式中返回最後一個值。 |
Max |
從指定運算式中返回所有非空值中的最大值。 |
Min |
從指定運算式中返回所有非空值中的最小值。 |
StDev |
從指定運算式中返回所有非空值中的標準差。 |
StDevP |
從指定運算式中返回所有非空值中的總體標準差。 |
Sum |
從指定運算式中返回所值的總和。 |
Var |
從指定運算式中返回所有非空值中的方差。 |
VarP |
從指定運算式中返回所有非空值中的總體方差。 |
報表格服務提供函數來支援運行時的匯總。圖3中顯示了相關的函數。
表 3
函數 |
功能 |
RowNumber |
在指定範圍內返回運行時產生所有行的數量。當於資料區域中使用文字框時,顯示在運算式顯示部分每個文字框執行個體的行數。用於指定表格行數或提供分頁符。在RowNumber(Nothing)中,關鍵字Nothing指定了在最外側資料區域中從第一行開始計數。 |
RunningValue |
使用指定函數從指定運算式中返回運行時的彙總。 |
報表格服務提供了下列導航範圍函數。表4中顯示了這些函數。
表4
函數 |
描述 |
InScope |
判斷當前報表專案執行個體是否在指定的範圍中。它使用資料集,分組或資料區域的名稱做為參數並返回布爾值。 |
Level |
在遞迴層次中返回當前層級的深度。 |
Previous |
返回之前的行。 |
報表渲染時的考慮
報表伺服器提供了一套磨人的渲染擴充。你可以從報表格服務中刪除擴充或添加自訂擴充支援新的渲染格式。
預設的渲染擴充包括了HTML,Excel,逗號分隔字元(CSV),XML,映像和PDF。
注意: 預設渲染擴充在報表格服務中可以用於渲染報表。使用SQL Server 2005報表檢視器控制項在本地產生的報表可以支援HTML報表渲染,但是不需要訪問其他的擴充。
你選擇的渲染擴充會影響報表的布局。例如,不是所有的渲染擴充支援強制的頁面分隔字元或者頁面分隔字元應用於頁面尺寸設定。表5中匯總一些差異。
表5
渲染擴充 |
基於報表專案或分組分頁 |
頁面尺寸 |
HTML |
可以 |
使用InteractiveHeight屬性 |
Excel |
可以 |
不可以 |
CSV |
不可以 |
不可以 |
XML |
不可以 |
不可以 |
Image |
可以 |
可以 |
PDF |
可以 |
可以 |
GDI (Window 表單) |
可以 |
使用InteractiveHeight屬性 |
如果你在設計報表之前你知道報表會被如何渲染,你可以針對目標格式最佳化報表布局。否則,以應該對各種可能的渲染擴充測試你的報表並找到和解決各式上的問題或異常。
接下來的部分包含了使用Excel,映像,PDF和HTML渲染擴充的一些建議。
Excel
報表格服務支援將報表渲染為Microsoft® Excel® 1997及以後版本。如果你計劃將報表渲染為Excel,你應該知道一些Excel渲染擴充的特殊屬性。例如:
◆在報表中每一個報表頁面將變為一個Excel的工作表。Excel不支援頁高和頁寬的概念,所以只有顯式定義的分頁符才能將頁面分割。
◆報表格服務不支援指定工作表名稱。
◆渲染擴充構建報表外的表格結構。
◆不支援個別單元中的背景圖片。
◆Excel除列表外的嵌套容器。
◆圖表被渲染成圖片,而不是Excel中的圖表。
◆矩形被渲染成儲存格組。如果舉行包含其他報表專案,矩形將變為儲存格範圍,矩形的邊框和背景色將應用於表格地區。
◆子報表將被作為矩形在同父報表中的工作表中渲染。
在指定Excel報表中使用表格代替列表
表格使用固定的列寬。這很好的滿足Excel報表中的表格格式。當渲染為Excel時,報表中的報表專案會像我們期望一樣排列。
與表格相比,列表是一種自由表單的風格。列表中的報表專案將被放置在工作表中像對於在報表中的位置。這樣會導致意想不到的結果。如果你的報表中使用了列表,要確認渲染成Excel的結果是可以接受的。
即使使用表格,如果在你的報表中頁首跨越多個列,Excel渲染擴充可能合併儲存格或引入新的列。這樣會在Excel試算表中影響資料的排序和操作。如果你計劃將報表渲染為Excel,請設法確認報表專案排列能將儲存格合并減到最小。
長報表的最大頁數
為了預防產生Excel產生錯誤,你應該注意冗長報表的頁數。報表中的每頁都會變成Excel中的一個工作表。然而,每一個活頁簿中為了限制對記憶體的使用,會有一個最大的工作表數量。如果報表頁面超過了這個限制,Excel會產生一個錯誤。
渲染為Excel時的顏色差異
支援一套預定義的顏色。當你渲染報表時,Excel渲染擴充將報表中的顏色應設成Excel支援顏色中最接近的顏色。
映像
映像渲染擴充可以將報表渲染成位元影像或圖元檔案。預設情況下,它將資料渲染成TIFF格式。然而他也可以產生被GDI+支援的任何格式,包括BMP,EMF,GIF,JPEG和PNG。
在報表伺服器中映像渲染處理在一個虛擬頁面中進行,並在這個頁面建立映像。結果,在任何用戶端上,基於映像的報表在字型和布局上看起來都是一樣的。
當你使用TIFF檔案時,你可以查看多頁面報表。然而,其他的映像格式為將為每一個報表頁面產生一個影像檔。
映像渲染也支援頁面高度,頁面寬度和頁面邊界。任何報表中包含的頁首和頁尾都會在報表邊界內被渲染。
使用映像渲染為所有的用戶端建立同樣的報表
如果你希望在所有用戶端看到同樣的報表,你應該使用映像渲染。特別是當報表渲染時,HTML報表使用用戶端子體和瀏覽器設定。這意味著當用戶端使用不同的瀏覽器時報表的布局會有所不同。因為影像檔在報表伺服器上格式化,它們渲染成的圖片在任何用戶端上的顯示都是一樣的。
在報表伺服器上安裝適當的字型
你應該確認在報表伺服器上安裝的正確的字型。這是因為報表實際上是在報表伺服器上渲染,它使用了在報表伺服器上所安裝的字型。
便攜文檔格式
便攜文檔格式(PDF)渲染擴充建立的報表可以使用Adobe Acrobat readers開啟查看。在很多方面上,PDF擴充類似於圖片擴充,除了下列重要的差異:
◆在PDF報表中字型沒有被嵌入到報表中。
◆文件引導模式被渲染成PDF書籤。
◆你可以在裝置選項中指定頁面的寬度高度、邊距和PDF的解析度。
◆渲染擴充建立的PDF1.3版本的檔案和Adobe Acrobat 4.0機器以後版本相容。
◆PDF渲染擴充不支援 RepeatWith屬性。
在客戶機中安裝適當的字型
PDF擴充無法在報表中嵌入字型。為了正確的查看報表的字型,你不僅需要在報表伺服器上確認安裝該字型,也要確認該字型在查看報表的用戶端中正確安裝了。另外字型替代現象很有可能發生。
HTML
HTML擴充可以產生與Microsoft® Internet Explorer,Mozilla Firefox及Apple Safari相容的HTML 4.0頁面。
HTML渲染和其他的渲染有以下的不同:
◆HTML渲染擴充在HTML中產生了一個包含所有報表控制項項的表格。控制項項將保持在報表布局時的位置。
◆位置和大小使用毫米(mm)為單位表示。渲染的最小單位是0.2毫米。
◆HTML不支援對象的重疊。這樣導致當報表顯示時布局被改變了。
◆在HTML報表中,子報表被渲染在DIV標籤中。
用戶端變化
當在用戶端顯示時,HTML報表使用瀏覽器的特性來設定。另外字型的變化,其他的瀏覽器設定可以做相應的處理改變。如果你想恰到好處的控制在所有用戶端上的布局,考慮使用映像渲染擴充。
不同瀏覽器的差異
SQL Server 2005報表格服務包括了對於不同瀏覽器的支援例如Microsoft Internet Explorer, Mozilla Firefox 和Apple Safari。儘管大多數的報表的特性在這些瀏覽器上都是被支援的,你也應該在相應瀏覽器上測試確認其滿足你的需求。
實用的報表設計技巧
本節提供了使用運算式來巧妙處理報表格式和布局的技巧和技術。
使用矩形保持對象的緊湊
在報表格服務中矩形可以被用於圖形元素或者對象的容器。做為對象容器,它可以是在一個頁面上的對象保持適當的距離並控制對象項目移動式的位置。
為了保持多個對象在同一個頁面中,可以將對象放在一個矩形內。你通過設定矩形的PageBreakAtStart或PageBreakAtEnd屬性在矩形的前後添加分頁符。
使用矩形控制報表專案的增加位置移動
在同一個矩形中的控制項相互間是同等的並且當控制項增長或移動時通過統一的規則在頁面中排布。例如:
◆報表專案通過通過各自的矩形來推動和置換。
◆報表專案不能和矩形外報表專案推動或置換,因為他們不在一個層級上。
◆如果需要,矩形可以增長來適應所包含的控制項。
當處理會擴充的對象時,你可以利用這個邏輯的功能。例如:
◆如果你為你的報表擴充預留出一些空白的空間,可以將表格和相應的空白空間放止於同一個矩形。當表格增長,它會被置於預留好的空白空間中。
◆如果你防止矩陣擴充出頁面的右側邊緣,可以將矩陣和一些空白放入同一個矩形中。
避免空白頁
有時當你將報表輸出到例如PDF或印表機這樣的物理頁面是,你可能會看到有空白頁面。通常,當報表本文超過紙面尺寸是會發生這種情況。
為了確認所有的內容適合於單一的紙張,本文加上頁邊的空白應該小於預定義好的紙面寬度。文字框和其他的報表專案可以導致本文寬度超過紙面寬度,即使當超出部分的內容不可見。另外,報表專案水平的增長(矩陣資料區域和圖片自動化佈建為Autosize或Fit)可以導致本文寬度的增長。
使用分頁提高大報表的效能
如果不去為一個返回大量資料的報表設定頁面大小或分頁符,一些報表格式將會嘗試將報表渲染成單頁。
例如,Excel沒有預設的固定式頁面面寬度。所以,如果你有一個很大的報表,Excel將嘗試將其渲染成一個工作表。通常,使用分頁符可提高使用者訪問報表時的效能,因為當渲染報表剩餘部分時,使用者可以查看報表的第一頁。
使用篩選器代替查詢參數
報表格服務有幾種方法動態過濾報表內容:
◆當返回叢資料來源擷取資料時使用查詢參數過濾資料。
◆應用於資料集或報表地區的報表篩選器,限制在報表中顯示的資料。
使用篩選器擷取所有的資料,但是只有和使用者相關的資料被顯示。這也許比在資料來源中過濾資料的效率要低。然而,這樣可以使我們只擷取一次資料並將資料存放區在快照中來服務於不同的使用者請求。換句話說,當我們使用查詢參數,每一個新的參數查詢你都要訪問資料來源。篩選器可以使我們執行快照並擷取所有參數的結果。
在表格中添加輪換條
也許你需要建立帶有隔行漸層形式的表格或矩陣的報表。 這種欄從視覺上可以更好地在一個頁面上跟蹤不同的行。
為了更好的類比用在產生大量報表的高速資料印表機中的老式綠條紙 你可以輪換條設定為綠色。
為了完成這個效果,可以使用Iif函數基於行數的奇偶性有條件指派背景色。例如:
=iif(RowNumber(Nothing) Mod 2,"PaleGreen","White")
在RDL檔案中的描述應該類似於如下代碼:
<TableCell>
<ReportItems>
<Textbox Name="SalesOrderID">
<Style>
<PaddingLeft>2pt</PaddingLeft>
<Format>d</Format>
<BackgroundColor>=iif(RowNumber(Nothing) Mod 2,"#c0ffc0","White")
</BackgroundColor>
<TextAlign>Right</TextAlign>
<PaddingBottom>2pt</PaddingBottom>
<PaddingTop>2pt</PaddingTop>
<PaddingRight>2pt</PaddingRight>
</Style>
<ZIndex>4</ZIndex>
<rd:DefaultName>SalesOrderID</rd:DefaultName>
<CanGrow>true</CanGrow>
<Value>=Fields!SalesOrderID.Value</Value>
</Textbox>
</ReportItems>
</TableCell>
在一個報表中的表格中在指定行後添加分頁符
你可以使用Ceiling 函數在表格中將行分組,並在每個分組後插入分頁符。
Ceiling函數返回不小於輸入參數的最小值。例如,每隔30行添加一個分頁符,你應該使用下列運算式分組:
=Ceiling(RowNumber(Nothing)/30)
在RDL中描述分組應該類似於下列描述:
<TableGroups>
<TableGroup>
<Grouping Name="PageGroup">
<GroupExpressions>
<GroupExpression>=Ceiling(RowNumber(Nothing)/30)</GroupExpression>
</GroupExpressions>
<PageBreakAtEnd>true</PageBreakAtEnd>
</Grouping>
</TableGroup>
</TableGroups>
在頁首和頁尾中添加全域變數值
在表6中顯示了Globals對象的成員,這些可以在報表的運算式中使用。
表6
名稱 |
類型 |
描述 |
PageNumber |
Integer |
當前頁數。僅在報表的頁首和頁尾中使用。 |
TotalPages |
Integer |
報表的總頁數。僅在報表的頁首和頁尾中使用。 |
ExecutionTime |
DateTime |
報表開始執行得日期和時間。 |
ReportFolder |
String |
包含報表的檔案夾的路徑,例如salesreportsudgeting 或c:salesudget |
ReportName |
String |
報表的名稱,例如 currentbudget. |
你可以在報表的頁首或頁尾中使用運算式顯示報表名稱和執行時間。時間通過.NET提供的短日期格式。例如:
=Globals.ReportName & ", dated " & Format(Globals.ExecutionTime, "d")
同樣也可以利用文字框將報表的當前頁數和總頁數顯示在頁首:
=Globals.PageNumber & " of " & Globals.TotalPages
在頁首中顯示報表專案
在長報表中你可能會希望在頁首中添加報表本文中的文字。例如,一個姓名地址錄在頁首重要顯示當頁中出現的第一個和最後一個名字。
為了實現這個功能,你可以在頁首上添加一個文字框,並使用First函數。為了在頁面上顯示第一次出現的LastName值,運算式應該類似於如下所示:
=First (ReportItems!LastName.Value)
同樣的,使用運算式函數Last 可以提供在頁面上顯示LastName 文字框的最後一個值 。例如
=Last (ReportItems!LastName.Value)
建立帶有條件式格式設定的切入串連
報表格服務可以通過擁護和報表的互動在報表中隱藏或顯示報表專案。
你可以使用這種功能在報表中建立切入串連。例如,通過點擊某個地區,使用者可以從匯總視圖中切入資料的詳細資料。
接下來,為包含該分組的文字框建立觸發開關項。然後當使用者點擊該文字框,隱含的資料變成可見的或資料不顯示。
結論
Microsoft SQL Server 2005 報表格服務提供了多種報表設計的選擇。本文提供了一些常規的指導方針和報表設計技巧,但是只涉及了部分該產品的功能。為了擷取更多的設計資訊和產品功能,請參考SQL Server 2005 聯機叢書。