前些時候才發現我忽略多時的好物一枚--ReportViewer及RDLC!

之前在SSRS上開發過幾張具備機密性的查詢報表,檢視報表前需先通過額外的身份識別關卡,並要管控每個人可視資料範圍不同,這些用程式搞定是小事一椿,但邏輯搬到SSRS後處處受限,七拼八湊才搞出個堪用但頗為複雜的解決方案。當得知RDLC可以不靠SSRS,只要設法自己生一個DataTable就能享有SSRS報表的相同便利性時,"相見恨晚"的懊悔又油然而生...

http://www.gotreportviewer.com/有一篇很好的FAQ介紹RDLC,去信取得原作者授權後,我翻譯改寫如下:

Q: ReportViewer 2008有什麼新功能?
A: 這篇Blog裡有ReportViewer 2008的新功能清單。

Q: ReportViewer 2008是否與Reporting Services 2008的新功能相容? (如Tablix)
A: 不行耶。Visual Studio 2008比SQL 2008的誕生早了好一陣子,所以ReportViewer 2008是以SSRS 2005 RDL為基礎設計的,ReportViewer應會在下次更新時加入RDL 2008的新功能。

Q: ReportViewer控制項是否被包含在SQL Server 2005/2008中?
A: 不不不,Report Server是SQL Server 2005/2008家族的成員, 但ReportViewer控制項不是。ReportViewer被包含在Visual Studio 2005/2008中。

Q: 要使用ReportViewer控制項需要安裝SQL Server嗎?
A: 嘿,不用,只要有.NET Framework 2.0就搞定了。

Q: 要使用ReportViewer控制項需要具有SQL Server授權嗎?
A: 哇哈哈,不用! ReportViewer控制項可以自由散佈,在本機模式(local mode)下不需任何SQL Server,啟用遠端模式(remote mode)時,則需要連上Report Server,而Report Server需要有SQL Server授權才能安裝使用。

Q: 報表的資料來源必須來自SQL Server資料庫嗎?
A: 報表的資料來源沒有任何限制,但與Reporting Service RDL不同的是,查詢資料的工作必須由應用程式自行完成,並以ADO.NET DataTables或Business Object集合的形式提供給ReportViewer,ReportViewer控制項完全不管你的資料是從哪裡生出來的。

Q: ReportViewer可以檢視SQL Server 2000 Report Server上的報表嗎?
A: 不行,在遠端模式(remote mote)下,ReportViewer控制項只能檢視SQL Server 2005 Report Server(SSRS)上的報表,但報表的資料來源則無限制,SQL Server 2000, Oracle, DB2... 皆可。

Q: ReportViewer控制項是.NET Framework的一部分嗎?
A: 並不是,ReportViewer控制項隨Visual Studio 2008發行,而非.NET Framework的一部分。

Q: 哪些版本的Visual Studio 2008包含ReportViewer?
A: 標準版以上都有(換句話說,只有Visual Web Developer Express沒有,但有其他解決方案)。

Q: RDL與RDLC格式的差別在哪裡?
A: RDL檔案是SQL Server 2005 Report Designer的產出結果;RDLC 檔案則是由Visual Studio 2008 Report Designer設計所得。
RDL與RDLC有相同的XML Schema,但RDLC中部分值(如Query Text)允許空白,因此RDLC無法直接發佈到SSRS上,除非用SQL Server 2005 Report Designer編輯並補上缺少的值。
RDL則完全相容於ReportViewer控制項,但是RDL少了一些讓設計階段產生自動Data-Binding的資訊,要在ReportViewer中使用,得加上些手工
注意,ReportViewer控制項不包含任何連線資料庫或執行查詢的邏輯,完全要由程式自行打理,甚至可以從非資料庫來源組出報表所需的資料。因此,RDL中的資料庫連線及查詢語句將會被忽略,不要期望ReportViewer會幫你連DB查資料,一切得自己寫程式處理,把報表所需的ADO.NET DataTable生出來。(這點是限制也是優點)

Q: RDLC的C是啥意思?
A: C代表Client-side processing. RDL則是Report Definition Language.

Q: 為何ReportViewer控制項在本機模式(local mode)下不支援參數提示與輸入功能?
A: 參數提示與輸入功能只有在遠端模式提供,理由是本機模式下,ReportViewer並不會主動執行查詢,只被動地接收DataTable成果,既然這些工作都由應用程式處理,ReportViewer無從亦不宜插手。

Q: 我安裝了Visual Studio 2008及Report Designer,卻找不到預覽(Preview)頁籤。SQL Server 2000 Report Designer裡那個預覽頁籤到哪裡去了?
A: 斯斯Report Designer有兩種,一種是Visual Studio 2008提供的,另一種則來自SQL Server 2005 box。預覽功能只有SQL 2005版的有,VS2008版的則要透過執行程式才會看到結果。理由很簡單,查詢資料的邏輯寫在程式碼裡,不把程式跑起來,就無從取得資料,何來預覽?

Q: 為什麼不能給個RDL就看到報表?
A: 遠端模式下,可以給個URL就直接看到報表。本機模式下,報表的資料來源要靠程式生,因此你必須在程式裡包辦開啟連線、查資料、取得DataTable、關閉連線等一連串工作,不過,這也賦與程式更多的設計彈性(想像一下,能將AD、XML、DB的結果整合成一個DataTable有多酷)。
不過別怕,靠著Visual Studio的Data Wizard以及ADO.NET DataAdpate元件,查詢資料一點都不難。

Q: 我從資料來源(Data Sources)視窗拖了一個欄位到報表中,但執行程式時只看到一列,要如何看到所有資料?
A: 要看到所有資料列,先拖一個Table或List到報表上,再拖欄位到Table或List上。

Q: 使用WebForms ReportViewer控制項時,先顯示"Report is being generated"訊息,但訊息一消失,報表卻連鬼影子都沒看到。
A: 如果你將ReportViewer的高度設為百分比,請刪除.aspx的XHTML DOCTYPE設定。說明

Q: 要使用xls匯出功能,必須先安裝Excel嗎?
A: 免,xls匯出功能並不依賴Excel,檢視時才需要。

Q: 使用PDF匯出功能需要取得Adobe授權嗎?
A: 不用,ReportViewer控制項並未使用到Adobe的技術產生PDF,PDF是公開標準,任何人都不需授權就可以產生PDF檔案。

Q: ReportViewer控制項有什麼功能限制?
A: 與Report Server相比,ReportViewer控制項不會自己連上DB及執行查詢,在本機模式下只能匯出Excel及PDF(遠端模式下則SSRS的全部格式都支援),ReportViewer控制項不支援自訂Renderer及Report Item。
SSRS除了匯出格式較多,還具有效能擴充性、集中儲存、統一管理、快取、訂閱等額外功能。


Comments

# by Ark

vs 2008 內附的 crystal report 10也是不錯用的好物 也可以不用reportserver 直接吃dataset viewer可匯出的格式更多~也支援套表列印 對AJAX支援一半~恩~要動一些手腳 像我就弄2個viewer一個放UpdatePanel內 一個放外面用div隱藏 再用code ScriptManager.RegisterStartupScript 把 找出viewer1的print 和匯出按鈕的clientid onclick事件 js到viewer2 上對應的click

# by Maxi Ng

To Ark, reportviewer 也不用reportserver,可以吃datatable也可以吃IEnumerable object. To Darkthread, 黑緒兄有試過VWD2008ExpressSP1+RV add-in嗎? 我裝不起來,他說語言版本不符合

# by treebird

To jeffery, 在測試中嘗試讓ReportViewer抓不到DB. 結果拋出錯誤如最下面所視,不知道ReportViewer是否有自定義錯誤,來避免拋出詳細錯誤的狀況. 先多謝你的指教 -- 處理報表時發生錯誤。 引動過程的目標傳回例外狀況。 在建立連接至伺服器時發生錯誤。當連接至 SQL Server 2005 時,失敗的原因可能是,在預設設定下,SQL Server 不允許遠端連接。 (provider: SQL 網路介面, error: 26 - 搜尋指定的伺服器/執行個體時發生錯誤)

# by Jeffrey

to treebird, 在我的認知裡,RDLC的資料來源要靠我們自己寫程式控制組成,應當可用try ... catch包住連接資料庫的程式片段,再?出友善的錯誤訊息才是,還是你採行了其他做法呢?

# by Ravon

黑緒兄有試過 讓報表 長成跟瀏覽器可試介面一樣大嗎? 他好像會長的過大(fittopage=true) 這樣條整為非100% 不就會出現雙層scrollbar

# by Maxi Ng

測試時沒問題,裝到某客戶的IIS上後有下列錯誤 懷疑是版本問題,要怎樣設定?GAC嗎? 找到的組件資訊清單定義與組件參考不符。 (發生例外狀況於 HRESULT: 0x80131040) 描述: 在執行目前 Web 要求的過程中發生未處理的例外情形。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。 例外詳細資訊: System.IO.FileLoadException: 找到的組件資訊清單定義與組件參考不符。 (發生例外狀況於 HRESULT: 0x80131040)

# by chinpig

大大 您太利害拉 我這幾天在測,想說我有傳參數到rdlc中,但都沒出現錯誤訊息,但畫面是空白,只有上面的左右鍵,但卻可以匯出資料,debug了好久,一值找不出原因,想說是不是自己傳參數出了問題,抓了好久,後來看到您寫的 Q: 使用WebForms ReportViewer控制項時,先顯示"Report is being generated"訊息,但訊息一消失,報表卻連鬼影子都沒看到。 A: 如果你將ReportViewer的高度設為百分比,請刪除.aspx的XHTML DOCTYPE設定。說明 原來是我把高度設為100% 詭異=..= 拿掉就跑出來了 謝謝您嚕

# by Jack

請問DataTable裡面有10筆資料,ReportViewer可以每頁只顯示一筆資料嗎? 下一頁在顯示第二筆... 請問可以做到這種效果嗎? thanks

# by Jeffrey

to Jack, 每頁一筆可從報表設計下手,利用分群限定筆數。例如: http://www.wiseowl.co.uk/blog/s257/ssrs-rows-per-page-pt2.htm

# by Rossi

久仰黑緒大大大名 想請教黑緒大大對於SSRS @ ASP.NET連接的相關問題 是否有辦法跳過IIS的驗證去讀取SSRS的資料; 最近為此問題所困,翻過Google大神依舊無太多相關資訊 故在此請教,還請不吝於賜教了

# by Jeffrey

to Rossi, 你指的SSRS @ASP.NET是指內嵌ReportViewer或Iframe顯示放在SSRS上的報表嗎?這種做法都是讓瀏覽器直接跟SSRS伺服器打交道,驗證得依SSRS的規定,難以迴避。 依我的理解,改用RDLC就能自由管理身份驗證,這是我們改用RDLC的重要因素之一。你有必須使用SSRS的理由,要繞過IIS驗證的原因又是什麼?要了解這些,才好找出有效的替代方案。

# by Rossi

Hellothere Jeffrey 因為客戶端使用想使用SSRS,並且嵌入到本自製系統中,希望的是1. 跳過IIS 驗證 (因為只要Click會轉到自己寫的asp.NET程式轉址中,而這途中遠端IIS就會強迫跳出Windows驗證需要輸入帳號密碼,造成不便) 2. 連線成功後,至少可以直接跳出SSRS內的所有報表。 不知道是否有替代解決方案,小弟不才因此困了幾天,還請大師不吝賜教

# by Jeffrey

to Rossi, 個人以為最佳的解法是將SSRS改成RDLC,但工程浩大,在很多情境不是選項。由你的描述,聽起來像是在Desktop Client內嵌瀏覽器元件開啟SSRS,如果使用者已使用AD帳號登入Windows,可善用IE的自動登入功能,免去再問一次密碼的過程(一般而言URL用機器名稱而不要用IP預設會自動用Windows帳號登入),再不然先用IE登入一次SSRS並要求記住帳號密碼也可考慮。 我想到的最下策是在Desktop Client中跳出帳號密碼對話框,在使用者連上SSRS前先在背後用記下的帳號密碼完成認證,但一來記錄使用者帳密有違資安原則,二則這類機制實作有些難度,但也是種做法。

# by Rossi

Hellothere Jeffrey 不好意思因為端午連假這時候才回應; IE/Chrome 的自動登入作法基本上是可行,但是每次使用都必須通過至少一次的IIS,使用者很不方便... 因為是在自有系統上面透過一個Button連接到SSRS Server... 又牽涉到使用者登入自有系統後所賦予的權限問題,這個問題一直很苦惱著我,參考MSDN以及一些先進之做法實在是想不出還有哪些方法可以跳過IIS直接進入SSRS Server... 還正在努力研究這塊中。

Post a comment


97 - 73 =