使用ReportViewer执行用户端报表定义文件(.rdlc)来产出报表
前言
以往使用ASP.NET WebForm进行网站开发时,笔者面对报表的产出多会使用ReportViewer来进行,并且搭配用户端报表定义文件(.rdlc)来设计报表外观,其实是相当灵活的解决方案;如今使用ASP.NET MVC进行开发,虽然View中无法加入任何WebForm Control了,但我们依旧可以建立一个共用WebForm页面,在此页面上加入熟悉的ReportViewer来协助产出报表。详细实践细节请参考以下文章。
实践说明
整体实践概念就是建立一个WebForm页面于ASP.NET MVC项目中,利用该WebForm页面来实践ReportViewer相关产出报表工作;最终当有报表产出需求时,仅需在Controller中传递ReportViewer所需相关资讯至WebForm页面中,利用该WebForm页面来呈现相对应之报表内容。以下进行实践说明。
建立 ReportViewer Web Form 作为报表页面
首先新增 ReportViewer.aspx 文件
加入 ScriptManager 与 ReportViewer 于 WebForm 表单中。
<%@ Register assembly="Microsoft.ReportViewer.WebForms, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" namespace="Microsoft.Reporting.WebForms" tagprefix="rsweb" %>
由于笔者希望共用 ReportViewer 页面,因此建立 ReportWarpper 类来封装 ReportViewer 所需之各项资讯,最终我们即可于 Controller 中操作该些资讯来产出不同报表表单。封装的资讯包含 rdlc 文件位置、数据来源(ReportDataSource、ReportParameter),以及是否直接下载报表控制旗标(IsDownloadDirectly)。
{ // Constructors public ReportWrapper() { ReportDataSources = new List(); ReportParameters = new List (); } // Properties public string ReportPath { get; set; } public List ReportDataSources { get; set; } public List ReportParameters { get; set; } public bool IsDownloadDirectly { get; set; } }
由于Request会先至Controller中,然后依产出报表内容来取得相关数据填入ReportWarpper中,再转址至 ReportViewer WebForm 页面中依据 ReportWarpper 资讯呈现报表;因为有跨页面消息传递需求,所以在此使用Session作为传递ReportWarpper媒介。接着就可依据 ReportWarpper 提供的资讯来实践 ReportViewer 产出报表共用逻辑,其实主要就是在设定户端报表定义文件(.rdlc)位置,并且给予数据来源资讯(ReportDataSource、ReportParameter),最后判断是否直接输出文件供用户下载使用。
{ protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { GenerateReport(); } } private void GenerateReport() { var ReportWrapperSessionKey = "ReportWrapper"; var rw = (ReportWrapper)Session[ReportWrapperSessionKey]; if (rw != null) { // Rdlc location RptViewer.LocalReport.ReportPath = rw.ReportPath; // Set report data source RptViewer.LocalReport.DataSources.Clear(); foreach (var reportDataSource in rw.ReportDataSources) { RptViewer.LocalReport.DataSources.Add(reportDataSource); } // Set report parameters RptViewer.LocalReport.SetParameters(rw.ReportParameters); // Refresh report RptViewer.LocalReport.Refresh(); // Download report directly if (rw.IsDownloadDirectly) { Warning[] warnings; string[] streamids; string mimeType; string encoding; string extension; byte[] bytes = RptViewer.LocalReport.Render( "Excel", null, out mimeType, out encoding, out extension, out streamids, out warnings); Response.Clear(); Response.AddHeader("Content-Disposition", "attachment; filename=sample.xls"); Response.AddHeader("Content-Length", bytes.Length.ToString()); Response.ContentType = "application/octet-stream"; Response.OutputStream.Write(bytes, 0, bytes.Length); } // Remove session Session[ReportWrapperSessionKey] = null; } } }
建立户端报表定义文件(.rdlc)
rdlc为报表设计的核心,可依需求来进行报表外观及数据呈现设计。举一个简单的范例,需求是列出今年度新进员工清单于报表中,最终报表产出画面如下,黄色部分为异动值,也就是要填入报表的数据。
首先加入名为 UserRpt 的 rdlc文件
设计划面如下,简单使用文字方块及数据表来呈现报表外观。
设定表单数据来源
在此步骤中可以把它想成是在设计报表的ViewModel,而常使用的数据型态分别为DataSet及Parameter,因此我们可以依照报表数据型态的不同来使用不同报表数据来源型态,以下分别进行实践。
ReportDataSource - DataSet
以下黄色区块很明显的就是Table部分,因此可以使用DataSet做为报表数据来源。
首先建立数据集文件(.xsd)并建立对应报表User Table之字段如下。
??
接着就可以在 rdlc 中加入刚定义之数据集
在此笔者加入UserRptDataSet中User表单作为报表数据集。记得要为此数据集取比较好识别的名称,因为后续在设定 Report Viewer 时会使用到,因此笔者都会使用 DataSetName_TableName 作为名称以便识别。
最后就绑定数据集中各字段至报表中即可。
Report Parameter
以下黄色区块由于是单笔资讯,因此偏好使用参数(Parameter)做为报表数据来源。
直接在 rdlc 中加入参数数据
建立一个名称为RptMakerParam报表参数。因为后续在设定 Report Viewer 时会使用到,记得要为此参数数据取个比较好识别的名称,否则参数一多的话可能会很混乱。
接着绑定参数数据至报表中
产出报表
最后写个测试网页,点选浏览报表时会透过ReportViewer来显示报表,而点选下载报表时就不会显示报表于画面上,而是直接下载报表为Excel文件。
浏览报表的controller代码如下
{ public ActionResult BrowseReport() { // Prepare data in report UserRptDataSet ds = new UserRptDataSet(); ds.User.AddUserRow("chris", "chris chen", "Taipei"); ds.User.AddUserRow("eunice", "eunice chen", "New Taipei"); // Set report info ReportWrapper rw = new ReportWrapper(); rw.ReportPath = Server.MapPath("/Report/Rdlc/UserRpt.rdlc"); rw.ReportDataSources.Add(new ReportDataSource("UserRptDataSet_User", ds.User.Copy())); rw.ReportParameters.Add(new ReportParameter("RptMakerParam", "CHRIS")); rw.IsDownloadDirectly = false; // Pass report info via session Session["ReportWrapper"] = rw; // Go report viewer page return Redirect("/Report/ReportViewer.aspx"); } }
点选后直接显示报表于页面上。
下载报表的controller代码如下,与上差别在设定IsDownloadDirectly旗标为true
点选下载报表连结后,直接下载保存为Excel文件
参考资讯
http://www.c-sharpcorner.com/UploadFile/ff2f08/incorporating-Asp-Net-mvc-and-sql-server-reporting-services/
http://pinnynet.blogspot.tw/2009/11/cliend-side-report.html
希望此篇文章可以帮助到需要的人
若内容有误或有其他建议请不吝留言给笔者喔 !
原文:大专栏 [ASP NET MVC] 使用ReportViewer执行用户端报表定义文件(.rdlc)产出报表