65.9K
CodeProject 正在变化。 阅读更多。
Home

Prototype MVC4 Razor ReportViewer? RDLC

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (24投票s)

2013年6月21日

CPOL

4分钟阅读

viewsIcon

181427

downloadIcon

13355

目的是尝试通过在视图中渲染 RDLC 报表来在 MVC razor 中实现类似 ReportViewer 的控件。此外,还尝试根据 MVC Razor 中的搜索过滤器条件输出报表。



目录
  1. 概述
  2. 需求规范/先决条件
  3. 设计规范
  4. 创建 RDLC 报表设计
  5. 模型视图控制器
  6. 改进领域
  7. 参考文献

1. 概述

本文的目的是帮助其他 MVC 开发者解决 MVC Razor 框架中与 Reportviewer 相关的问题。坦率地说,这是一个尝试!我搜索了在线方法/方法来将 Reportviewer 整合到 MVC Razor 中,但所有搜索都以“没有替代方案”而告终。我提出了一个小型原型,我们可以在其中创建和构建类似 ReportViewer 组件的基于搜索的报表。



 



2. 问题陈述 / 先决条件

我们需要在 MVC Razor 中构建简单的基于过滤器的报表。将有输入搜索过滤器条件以表格形式显示报表。


为构建解决方案,我们使用了 VS2012 和 MVC4 Razor 架构。


3. 设计规范

  1. 设计 RDLC 报表。
  2. 创建域模型 **SearchParameterModel 和 ***WorldReportModel。SearchParameterModel 是一个类对象,用于存储用户输入的报表过滤器条件。然后,此搜索参数在按钮单击事件触发的 HTTPost 上传递到控制器。WorldModel 用于存储数据源中的记录。
  3. 创建视图 ReportViewer.chtml。
  4. 创建控制器 ReportViewerController
  5.  
    我们得到了什么?


  1. 通过此解决方案,我们可以灵活地使用存储过程输出(将 RDLC 绑定到 RDLC 的数据源),并带有 MVC Razor 视图所需的输入。
  2. 通过此解决方案,我们可以下载 PDF、Word 或 Excel 格式的报表。
  3. 通过此解决方案,我们可以使用img src="@Url.Action("GenerateAndDisplayReport", "Report", new { territory = Model.Territory, format = Model.Format })" 来在 Web 中渲染报表

 



4. 创建 RDLC 报表设计

1. 在解决方案中添加新项报表 - Report1.RDLC。



2. 添加新项 - 数据集 - Dataset1.xsd。使用设计器视图手动添加数据表中的列。列名应与 Models-ReportModels(类 SearchParameterModel)中的公共属性匹配。任何偏差都会导致错误。



完成上述步骤后……请查看下方







3. 单击 RDLC 文件,拖放所需的 Tablix 控件,并使用所需的数据集字段进行填充。为此,请单击菜单 - 视图 - Reportdata。手动添加新数据集,此窗体将为您提供选择我们最初创建的数据集1的选项。



更多帮助。请参阅我的文章。设计 RDLC 中的报表数据结构



 

图 1. 为 RDLC 报表数据源映射创建 dataset1 架构。



图 2. 我们可以像下面的截图一样在报表数据中引用此 dataset1。右键单击并添加新数据集。





5. 模型视图控制器

模型:ReportModels

SearchParameterModel 对象充当占位符,用于接受输入参数以过滤报表结果集。此类还有助于显示标签的内容,并用于验证输入字段。format 属性用于识别报表的格式,如 PDF、Word 或 Excel。

                  public class SearchParameterModel
    {
        
            [Display(Name = "Search By Terrritory")]
            public string Territory
            {
                get ;
 
                set ;
            }
            public string Format
            {
                get;
 
                set;
            }
 
    }
            

WorldModel 类是报表结果集的数据结构。稍后将填充此项并绑定报表 RDLC 数据源。一个警告,请定义 getter 和 setter 属性中的私有成员,否则 RDLC 数据集将无法识别字段或列。这会导致报表错误。

 public class WorldModel
    {
       
            private string m_Territory;
            private string m_Country;
            private string m_Year;
            private string m_Stats;
 
           
            public string Territory
            {
                get {return m_Territory ; }
 
                set {value = m_Territory;}    
            }
 
            public string Country
            {
                get { return m_Country; }
 
                set { value = m_Country; }
            }
 
            public string Year
            {
                get { return m_Year; }
 
                set { value = m_Year; }
            }
 
            public string Stats
            {
                get { return m_Stats; }
 
                set { value = m_Stats; }
            }
            public WorldModel()  { }
 
            public WorldModel(string territory, string country, string year, string stats)
            {
                m_Territory      = territory;
                m_Year   = year;
                m_Country = country;
                m_Stats = stats;
            }
    }




视图

1. 视图是一个简单的表单,带有一个输入文本框和一个按钮。我们有一个图像标签用于在部分中渲染报表。单击按钮时,我们通过 HttpPost-ActionResult 将输入值传递给控制器。

2. 视图与强类型模型绑定 —> ViewModel。@model MvcApplication3.Models.SearchParameterModel

3. 容器:我们使用 @Html.TextBoxFor(m => m.Territory) 捕获/存储文本字段值。

4. 单击按钮时,通过调用控制器 public ViewResult ReportViewer(SearchParameterModel um) 来检查 Model 集合对象是否已填充或存在。当由于按钮单击事件发生 httppost 时会调用此方法。

5. 现在,***关键之处在于,我们现在可以将输入参数的值传回视图,并在 @Url.Action("GenerateAndDisplayReport", "Report", new { territory = Model.Territory, format = Model.Format }).. 检查 @if(Model !=null)  中初始化它。

上述工作流程此时可能有些繁琐。您需要做的就是下载源代码并理解代码执行流程。MVC 都是关于概念和实践的。





控制器 (Controller)

1. ActionResult ReportViewer() 在报表表单的页面加载时首次调用。即,当我们单击菜单报表链接时。

2. 当由于按钮单击事件发生表单发布时,会调用 ActionResult ReportViewer(SearchParameterModel um)

3. FileContentResult GenerateAndDisplayReport(string territory, string format) 用于将响应流绑定并填充到 img 中。有关更多详细信息,请查看视图 @URl.Action。

 public class ReportController : Controller
    {
        //
        // GET: /Report/
        [AllowAnonymous]
        public ActionResult ReportViewer(string returnUrl)
        {
            ViewBag.ReturnUrl = returnUrl;
            return View();
        }
 
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ViewResult ReportViewer(SearchParameterModel um)
        {
            return View(um);
        } 
 
        public FileContentResult GenerateAndDisplayReport(string territory, string format)        
        {            
            LocalReport localReport = new LocalReport();            
            localReport.ReportPath = Server.MapPath("~/Content/Report1.rdlc");
            IList<WorldModel> customerList = new List<WorldModel>();
            customerList.Add(new WorldModel("Europe", "Sweden", "2001", "1823"));
            customerList.Add(new WorldModel("Europe", "Sweden", "2002", "1234"));
            customerList.Add(new WorldModel("Europe", "Sweden", "2003", "9087"));
 
            customerList.Add(new WorldModel("Europe", "Denmark", "2001", "6793"));
            customerList.Add(new WorldModel("Europe", "Denmark", "2002", "4563"));
            customerList.Add(new WorldModel("Europe", "Denmark", "2003", "1897"));
 
            customerList.Add(new WorldModel("Europe", "Norway", "2001", "5632"));
            customerList.Add(new WorldModel("Europe", "Norway", "2002", "9870"));
            customerList.Add(new WorldModel("Europe", "Norway", "2003", "2367"));
 
            customerList.Add(new WorldModel("Asia", "India", "2001", "1980"));
            customerList.Add(new WorldModel("Asia", "India", "2002", "9765"));
            customerList.Add(new WorldModel("Asia", "India", "2003", "6789"));
 
            customerList.Add(new WorldModel("Asia", "Japan", "2001", "9871"));
            customerList.Add(new WorldModel("Asia", "Japan", "2002", "2987"));
            customerList.Add(new WorldModel("Asia", "Japan", "2003", "1256"));
 
            customerList.Add(new WorldModel("North America", "United States", "2001", "9871"));
            customerList.Add(new WorldModel("North America", "United States", "2002", "9871"));
            customerList.Add(new WorldModel("North America", "United States", "2003", "9871"));
 
 
            customerList.Add(new WorldModel("North America", "Canada", "2001", "9871"));
            customerList.Add(new WorldModel("North America", "Canada", "2002", "9871"));
            customerList.Add(new WorldModel("North America", "Canada", "2003", "9871"));
 
            customerList.Add(new WorldModel("North America", "Mexico", "2001", "9871"));
            customerList.Add(new WorldModel("North America", "Mexico", "2002", "9871"));
            customerList.Add(new WorldModel("North America", "Mexico", "2003", "9871"));
 
            customerList.Add(new WorldModel("South America", "Brazil", "2001", "9871"));
            customerList.Add(new WorldModel("South America", "Brazil", "2002", "9871"));
            customerList.Add(new WorldModel("South America", "Brazil", "2003", "9871"));
 
            customerList.Add(new WorldModel("South America", "Columbia", "2001", "9871"));
            customerList.Add(new WorldModel("South America", "Columbia", "2002", "9871"));
            customerList.Add(new WorldModel("South America", "Columbia", "2003", "9871"));
 
            customerList.Add(new WorldModel("South America", "Argentina", "2001", "9871"));
            customerList.Add(new WorldModel("South America", "Argentina", "2002", "9871"));
            customerList.Add(new WorldModel("South America", "Argentina", "2003", "9871"));
            ReportDataSource reportDataSource = new ReportDataSource();
            reportDataSource.Name = "DataSet1";
            if (territory != null)
            {
                var customerfilterList = from c in customerList
                                         where c.Territory == territory
                                         select c;
 
                
                reportDataSource.Value = customerfilterList;
            }
            else
                reportDataSource.Value = customerList;
            
            localReport.DataSources.Add(reportDataSource);            
            string reportType = "Image";            
            string mimeType;            
            string encoding;            
            string fileNameExtension;                       
             
            Warning[] warnings;           
            string[] streams;            
            byte[] renderedBytes;             
            //Render the report            
            renderedBytes = localReport.Render(reportType, deviceInfo, out mimeType, out encoding, out fileNameExtension, out streams, out warnings);   
            //Response.AddHeader("content-disposition", "attachment; filename=NorthWindCustomers." + fileNameExtension); 
            if (format == null)
            {
                return File(renderedBytes, "image/jpeg");
            }
            else if (format == "PDF")
            {
                return File(renderedBytes, "pdf");
            }
            else {
                return File(renderedBytes, "image/jpeg");
            }
        }   }




6.改进领域

此解决方案唯一的问题是,它无法取代现有的报表查看器。上述解决方案不够健壮,因为它在 Web 表单 Razor 视图中渲染报表为图像。



这需要进一步研究,并且必须探索 HTML 渲染选项,但我未能实现。也许 MVC razor 架构缺少像 Report Viewer 这样强大的 Web 控件。

7. 参考文献

报表 RDLC 设计教程

 
© . All rights reserved.