2016年7月3日 星期日

[RDLC] MVC專案建立Reporting報表( Report Viewer )

 #RDLC   #Report viewer   #MVC 

Introduction


此篇文章將介紹如何在MVC專案中,加入Report viewer來開發RDLC報表。
由於Report viewer是含有View StateWeb form控制項,因此解法是在MVC專案中加入Web form page來開發報表。


Implement



MVC專案加入Web form (.ASPX)

 

Web form 放入ReportViewerScriptManager控制項







 


設定資料來源及資料集

取得資料來源的方式,採用傳統ADO.NET的方式會比較方便,因為RDLC的資料來源為資料集”(DataSet)。 當然也可以使用ORM,只是需要再轉為DataTable再放入DataSet

另外為了查詢資料邏輯的彈性和維護性,我建議是查詢建立成View,然後以Store Procedure帶入參數取得 View的資料。

l   Store Procedure

CREATE PROCEDURE [dbo].[usp_getCitys]
    @CityName NVARCHAR(20) --傳入之城市名稱
AS
BEGIN
   
    SET NOCOUNT ON;
    SELECT Id,Name
    FROM Citys
    WHERE Name LIKE '%'+ @CityName +'%';
END



l   DataSet

接著在專案加入對應的資料集(.XSD)



設計對應欄位
並記住每個DataTable 的名稱,後面程式碼會使用到。




l   RDLC

下一步就是設計報表囉! 在專案加入報表(.RDLC)

 


並在報表資料中,加入我們剛才建立的資料集。


 

PS. 資料集的名稱很重要唷! 等下我們寫程式碼的時候會用到。

最後請設計RDLC 下一步,我們要開始寫程式碼把資料從Store Procedure讀進Dataset,再將DataSet丟到RDLC


查詢程式

回到Web formPage load function, 加入以下程式

l   Page_Load

//Set base permission, 避免'System.Security.Permissions.SecurityPermission' 的使用權限要求失敗
rptViewer.LocalReport.SetBasePermissionsForSandboxAppDomain(
      new PermissionSet(PermissionState.Unrestricted));

rptViewer.ProcessingMode = ProcessingMode.Local; //Use local report viewer's engine
rptViewer.ShowPrintButton = true; //顯示列印鈕
rptViewer.LocalReport.EnableExternalImages = true;
rptViewer.LocalReport.ReportPath = Server.MapPath("~/Reports/Rdlc/City.rdlc");
rptViewer.LocalReport.DataSources.Clear();

#region  取得資料
DataSetCity dsCity = getCityData(cityName);
ReportDataSource datasource = new ReportDataSource("DataSetCity", dsCity.Tables[0]);
rptViewer.LocalReport.DataSources.Add(datasource);
#endregion

PS. cityName 是使用者輸入的參數,由於.aspx (Web form) 無法以MVC預設的Routing rule來執行,因此在這邊我仍是選擇以MVCView為主,以iframe內嵌這張Web form 並將使用者參數用URL參數的方式帶入到Web form

var cityName = Request.QueryString["cityName"].ToString();


l   getCityData()

private DataSetCity getCityData(string cityName)
{               
var rtnVal = new DataSetCity();

          var connString = ConfigurationManager.ConnectionStrings["JbDbContext"].ConnectionString;
          var sqlConn = new SqlConnection(connString);
          SqlCommand cmdReport = new SqlCommand("usp_getCitys", sqlConn);
          SqlDataAdapter daReport = new SqlDataAdapter(cmdReport);

          using (cmdReport)
          {
             SqlParameter questionIdPrm = new SqlParameter("@CityName", cityName);
             cmdReport.CommandType = CommandType.StoredProcedure;
             cmdReport.Parameters.Add(questionIdPrm);
daReport.Fill(rtnVal, "DataTableCity");
          }
          return rtnVal;
}

PS. 程式碼中,黃色底的部分就是在設計過程中,需要記住的DataSet, SP, DataTable 名稱。


執行結果


 

  


Reference

沒有留言:

張貼留言