使用物件陣列作為 RDLC 報表資料來源

我喜歡 RDLC 勝過 Report Server 報表的原因之一是報表資料來源不限定來自資料庫,可以是自己組裝的 DataTable, 甚至是自訂資料物件,具有無比的應用彈性。這篇文章用一個極簡的範例,展示如何使用 List<T> 當成 RDLC 資料來源。

我用中國重大歷史事件一覽表當素材:

先設計一個包含 Year 與 Description 屬性的 Event 類別代表每個歷史事件,寫一個 MyHistoryStore 透過 GetAllEvents() 解析文字檔吐回 List<Event>。這裡有個重點,傳回結果型別必須是 IEnumerable(T[]、List<T> 都算),RDLC 才會視為可用的資料來源。(參考:To be accessible as a data source, a class must expose a method or property that returns an IEnumerable. You can add a class or a reference to the assembly for a class to your project.)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Web.Hosting;
 
namespace RDLCTest
{
    public class Event
    {
        public string Year { get; set; }
        public string Description { get; set; }
    }
 
    public class MyHistoryStore
    {
        public static List<Event> GetAllEvents()
        {
            using (var sr = new StreamReader(
                HostingEnvironment.MapPath("~/App_Data/history.txt")))
            {
                string line;
                List<Event> list = new List<Event>();
                while ((line = sr.ReadLine()) != null)
                {
                    var i = line.IndexOf(",");
                    if (i > 0)
                    {
                        list.Add(new Event()
                        {
                            Year = line.Substring(0, i),
                            Description = line.Substring(i + 1)
                        });
                    }
                }
                return list.ToList();
            }
        }
 
    }
}

上述物件寫好記得先編譯一次,報表設計精靈才能從 DLL 中找出可用的資料屬性或方法。接著我們在專案中新増「Report Wizard」(開 Report 純手工改 RDLC XML 硬幹也成,但非鐵血硬漢勿試):

使用 Visual Studio 2017 新増 Report Wizard 時可能跳出下警告,只要你的 Report Designer 不是來路不明,就信任吧!

進入 Report Wizard 的 DataSet 屬性設定介面,先輸入 DataSet 名稱(本例用 HistoryDataSource,這個名字要記下來等等會用到),在 Data Source 下拉選單選取專案 NameSpace(本例為RDLCTest),接著 Available datasets 下拉選單應可找到剛才寫好的 MyHistoryStore(GetAllEvents) (記得在此步驟前專案要先編譯過,不然會找不到),選擇後右方會出現 Year、Description 欄位資料,代表 Wizard 已正確找到方法並識別出資料物件屬性。

接下來的操作與一般 RDLC 報表設計相同,在此不多贅述。

提示幾個設計報表要注意的小地方。

下圖白色部分是 Body 的範圍,要設定整張報表設定,要在白色範圍之外按右鍵,選「Report Properties」。

如果報表打算列印出來,就要留意紙張的尺寸、邊距。

欄位寬度總和記得不要超出紙張寬度減去邊距,不然每頁會印成兩張,實務上我習慣直接敲尺寸數字,比憑直覺拖拉精準。

Server 端的寫法很簡單,指定 ReportPath、DataSources.Add() 一個 ReportDataSource,建構時傳入 DataSet 名稱與 IEnumerable 就搞定了。這裡的 DataSet 名稱要輸入我們在 Report Wizard 一開始設定 DataSource 時給的名字-HistoryDataSource,若名字不符會產生「尚未提供資料來源 'HistoryDataSource' 的資料來源執行個體。」錯誤。(關於 ReportViewer 使用說明請參考前文

    public partial class Report : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                rptViewer.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Local;
                rptViewer.PageCountMode = Microsoft.Reporting.WebForms.PageCountMode.Actual;
                rptViewer.LocalReport.ReportPath = Server.MapPath("~/ObjDataSrcReport.rdlc");
                rptViewer.LocalReport.DataSources.Add(
                    new Microsoft.Reporting.WebForms.ReportDataSource("HistoryDataSource", 
                    MyHistoryStore.GetAllEvents()));
            }
        }
    }

薑!薑!薑!薑~ 搞定收工。

最後補充,PageCountMode 預設為 Estimate,頁數會顯示成 1 of 2?、2 of 3?,看不出實際總頁數。要設定為 Actual 才會顯示正確總頁數,Estimate 模式能避免某些情境下為取得總頁數拖累效能,本案例為記憶體中的資料物件無此疑慮,可放心設成 Actual。

歡迎推文分享:
Published 02 June 2017 06:38 AM 由 Jeffrey
Filed under:
Views: 4,355



意見

# Yang said on 03 July, 2017 05:31 AM

試過蠻多次的

Available DataSet選單能出現Event,但是GetAllEvents()一直沒出現。

重新建置蠻多次也沒出現,真是神奇...

使用工具:vs 2015 ent、reportviewer 2010

# Jeffrey said on 03 July, 2017 10:13 AM

to Yang, 聽不出什麼頭緒,要不要分享範例專案讓大家幫看?

# Yand said on 07 August, 2017 03:20 AM

阿呀,將近一個月了,其實我以為過半年了。閒來沒事來回來看我的問題。

我剛試看還是沒有GetAllEvents(),作為替代使用Event,其他步驟都差不多,一樣有資料XD。

原本的構想是先從資料庫撈資料,再餵資料進去,結果發現報表精靈產生Adapter的方法都是獨立的。後來改用這樣餵去會比較方便ㄎㄎ。

報表功能摸索中。

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<June 2017>
SunMonTueWedThuFriSat
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication