在上篇《會員管理系統的設計和開發(1)》介紹了關於會員系統的一些總體設計思路和要點,經過一段時間開發,軟件終於完成並發布。在這期間,碰到了不少技術難點,並積累了不少開發心得和經驗,本篇繼續介紹這個開發過程中相關的技術要點,主要介紹其中RDLC報表的相關操作,如報表的設計和通用的動態加載模塊的處理等內容。
什么是RDLC呢,它的全稱是Report Definition Language Client-Side,原來是微軟基於SQL Server 報表服務中經提供了一種被稱為報表定義語言(Report Definition Language, RDL)的改進版本,增加了客戶端處理報表功能,在WinForm和WebForm中均可以使用這種報表。
1、RDLC報表的設計
我們知道,RDLC報表展現是基於一個定義的報表文件的,一般是以rdlc后綴名的報表文件,在VS里面新建一個項,選定報表文件即可,如下所示。
RDLC的報表設計界面,提供了很多相關的控件進行繪制。
通過這些操作我們可以創建一些報表的元素在里面,如可以增加一些數據字段和列表字段在里面,最簡單的報表例子里面,可以增加一些圖片,標題,列表等內容,如下所示。
但往往這個只是測試階段的學習,一般情況下,我們的報表比上面的規范很多,要考慮樣式還有布局設計等方面,下面給出一些我會員系統里面的報表例子供參考對比。
下面是一個會員消費清單的報表設計,包括總的消費情況和明細報表設計。
以及一個會員身份的打印報表設計。
設計報表完成,只是完成了一部分工作,我們還需要建立數據集,把字段綁定到報表上面去,如上面的[Name]這樣標識的就是字段已經綁定的了,一開始這些可能是沒有的,需要我們先創建數據集對象。
創建數據集對象,可以選擇是DataSet類型的或者是實體類型的,網上介紹很多是基於DataSet方式的,由於我的Winform框架及整個系列的產品是基於實體類的,因此我的報表創建的數據集對象也是基於實體對象的。
從上面可以看出,創建的數據集對象,是引用我的實體類對象,里面包含了很多對象屬性,非常容易理解。
創建了相應的數據集對象后,我們進一步就是把這些信息綁定到設計的報表上面了。
先在報表視圖里面,把列表對象選中,綁定它的數據集對象,操作如下面兩個圖所示。
這樣我們就可以隨意指定列表里面的列的字段綁定操作了。
2、RDLC報表的動態加載
通過第一節介紹的報表設計和數據集對象的創建,然后進行綁定操作后,基本上設計部分就已經完成了,注意的就是調整好對應的格式,加載測試后進行微調整即可了。
本小節繼續介紹,如何把數據進行動態加載進行綁定。
為了實現報表的預覽,我們需要在UI項目里面添加下面兩個程序集對象。
然后在一個預覽報表的窗體里面,放置一個報表查看控件ReportViewer,設計報表預覽界面窗體如下所示。
以后我們設計的報表,就准備通過這個界面進行展現的了。
通過ReportViewer我們可以獲得LocalReport對象的引用,然后對它進行處理即可。
LocalReport report = this.rpViewer.LocalReport;
報表的數據綁定,主要就是增加報表對象里面的對應的ReportDataSource對象即可。
通過報表對象LocalReport,我們可以使用代碼增加對應的數據源給它的報表對象,這樣我們需要展現的報表數據源就可以和報表進行綁定了,具體的處理代碼如下所示。
那么我們如何在界面窗體里面進行報表的綁定操作呢?
封裝好通用的報表展現界面后,我們只需要調用他們的接口進行綁定一個新的報表和數據源了。具體代碼如下所示。
private void menuPrintReport_Click(object sender, EventArgs e) { string headerID = this.winGridViewPager1.gridView1.GetFocusedRowCellDisplayText("ID"); if (!string.IsNullOrEmpty(headerID)) { MemberConsumptionInfo consumptionInfo = BLLFactory<MemberConsumption>.Instance.FindByID(headerID); if (consumptionInfo != null) { //修改一些屬性值 //會員姓名 consumptionInfo.Data1 = BLLFactory<Member.BLL.Member>.Instance.GetNameByID(consumptionInfo.Member_ID); consumptionInfo.Data2 = SecurityHelper.GetFullNameByID(consumptionInfo.Creator); List<MemberConsumptionInfo> list = new List<MemberConsumptionInfo>(); list.Add(consumptionInfo); List<ConsumptionDetailInfo> detailList = BLLFactory<ConsumptionDetail>.Instance.FindByBillNo(consumptionInfo.BillNo); foreach (ConsumptionDetailInfo info in detailList) { //修改ProductID為商品編碼 info.Product_ID = BLLFactory<MemberProduct>.Instance.GetHandNoByID(info.Product_ID); } ReportViewerDialog dlg = new ReportViewerDialog(); dlg.DataSourceDict.Add("MemberConsumptionInfo", list); dlg.DataSourceDict.Add("ConsumptionDetailInfo", detailList); dlg.ReportName = "WHC.Member.ConsumptionReport"; AppConfig config = new AppConfig(); string companyName = config.AppConfigGet("CertificatedCompany"); dlg.Parameters.Add("CompanyName", companyName); dlg.ShowDialog(); } } }
3、RDLC報表的展現效果
在上面兩個小節里面,我們已經介紹過RDLC報表如何設計、如何綁定到ReportViewer報表預覽界面上了,還有也說明了如何在主窗體里面使用數據源進行動態的加載操作,但到底具體的報表展現效果如何呢,下面我給出幾個案例作為參考。
1)消費清單報表
2)收費記錄報表
3)會員卡片打印報表