[ASP NET MVC] 使用ReportViewer执行用户端报表定义文件(.rdlc)产出报表

使用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 文件

image

加入 ScriptManager 与 ReportViewer 于 WebForm 表单中。

image

<%@ 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为报表设计的核心,可依需求来进行报表外观及数据呈现设计。举一个简单的范例,需求是列出今年度新进员工清单于报表中,最终报表产出画面如下,黄色部分为异动值,也就是要填入报表的数据。

image

首先加入名为 UserRpt 的 rdlc文件

image

设计划面如下,简单使用文字方块及数据表来呈现报表外观。

image

设定表单数据来源

在此步骤中可以把它想成是在设计报表的ViewModel,而常使用的数据型态分别为DataSet及Parameter,因此我们可以依照报表数据型态的不同来使用不同报表数据来源型态,以下分别进行实践。

ReportDataSource - DataSet

以下黄色区块很明显的就是Table部分,因此可以使用DataSet做为报表数据来源。

image

首先建立数据集文件(.xsd)并建立对应报表User Table之字段如下。

image?? image

接着就可以在 rdlc 中加入刚定义之数据集

image

在此笔者加入UserRptDataSet中User表单作为报表数据集。记得要为此数据集取比较好识别的名称,因为后续在设定 Report Viewer 时会使用到,因此笔者都会使用 DataSetName_TableName 作为名称以便识别。

image

最后就绑定数据集中各字段至报表中即可。

image

Report Parameter

以下黄色区块由于是单笔资讯,因此偏好使用参数(Parameter)做为报表数据来源。

image

直接在 rdlc 中加入参数数据

image

建立一个名称为RptMakerParam报表参数。因为后续在设定 Report Viewer 时会使用到,记得要为此参数数据取个比较好识别的名称,否则参数一多的话可能会很混乱。

image

接着绑定参数数据至报表中

image

产出报表

最后写个测试网页,点选浏览报表时会透过ReportViewer来显示报表,而点选下载报表时就不会显示报表于画面上,而是直接下载报表为Excel文件。

image

浏览报表的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");  
    }
}

点选后直接显示报表于页面上。

image

下载报表的controller代码如下,与上差别在设定IsDownloadDirectly旗标为true

image

点选下载报表连结后,直接下载保存为Excel文件

image

参考资讯

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)产出报表

相关文章
相关标签/搜索
每日一句
    每一个你不满意的现在,都有一个你没有努力的曾经。