Prototype MVC4 Razor ReportViewer? RDLC






4.83/5 (24投票s)
目的是尝试通过在视图中渲染 RDLC 报表来在 MVC razor 中实现类似 ReportViewer 的控件。此外,还尝试根据 MVC Razor 中的搜索过滤器条件输出报表。
目录
1. 概述
本文的目的是帮助其他 MVC 开发者解决 MVC Razor 框架中与 Reportviewer 相关的问题。坦率地说,这是一个尝试!我搜索了在线方法/方法来将 Reportviewer 整合到 MVC Razor 中,但所有搜索都以“没有替代方案”而告终。我提出了一个小型原型,我们可以在其中创建和构建类似 ReportViewer 组件的基于搜索的报表。
2. 问题陈述 / 先决条件
我们需要在 MVC Razor 中构建简单的基于过滤器的报表。将有输入搜索过滤器条件以表格形式显示报表。
为构建解决方案,我们使用了 VS2012 和 MVC4 Razor 架构。
3. 设计规范
- 设计 RDLC 报表。
- 创建域模型 **SearchParameterModel 和 ***WorldReportModel。SearchParameterModel 是一个类对象,用于存储用户输入的报表过滤器条件。然后,此搜索参数在按钮单击事件触发的 HTTPost 上传递到控制器。WorldModel 用于存储数据源中的记录。
- 创建视图 ReportViewer.chtml。
- 创建控制器 ReportViewerController
我们得到了什么?
- 通过此解决方案,我们可以灵活地使用存储过程输出(将 RDLC 绑定到 RDLC 的数据源),并带有 MVC Razor 视图所需的输入。
- 通过此解决方案,我们可以下载 PDF、Word 或 Excel 格式的报表。
- 通过此解决方案,我们可以使用
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 控件。