asp.net-mvc 在 ASP.NET MVC 中以 HTML 格式呈现 RDLC 报告
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7991167/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rendering an RDLC report in HTML in ASP.NET MVC
提问by William Niu
I would like to render an RDLC report in HTML within an ASP.NET MVC project.
我想在 ASP.NET MVC 项目中以 HTML 格式呈现 RDLC 报告。
I successfully made a prototype that renders an RDLC report in PDF, Excel, and TIFF image, with the help of this article. But I was surprised that HTML is not one of the default available formats in LocalReport.Render().
在这篇文章的帮助下,我成功地制作了一个原型,可以在 PDF、Excel 和 TIFF 图像中呈现 RDLC 报告。但令我惊讶的是 HTML 不是LocalReport.Render().
I came across this article, which describes a trick to enable the rendering format of HTML4.0, but I think that is only for a ReportViewercontrol (I could be wrong though).
我看到这篇文章,它描述了启用 HTML4.0 呈现格式的技巧,但我认为这仅适用于ReportViewer控件(尽管我可能是错的)。
The question is, in MVC how to render an RDLC report in HTML just like a ReportViewdoes (see the screenshot below)?
问题是,在 MVC 中如何像 aReportView一样在 HTML 中呈现 RDLC 报告(请参见下面的屏幕截图)?


回答by Md. Nazrul Islam
This is a simple task. You can follow the following steps.
这是一个简单的任务。您可以按照以下步骤操作。
- Create a folder in your solution and give a name Reports.
- Add a ASP.Net web form and named it ReportView.aspx
Create a Class ReportData and add it to the Reports folder. Add the following code to the Class.
public class ReportData { public ReportData() { this.ReportParameters = new List<Parameter>(); this.DataParameters = new List<Parameter>(); } public bool IsLocal { get; set; } public string ReportName { get; set; } public List<Parameter> ReportParameters { get; set; } public List<Parameter> DataParameters { get; set; } } public class Parameter { public string ParameterName { get; set; } public string Value { get; set; } }Add another Class and named it ReportBasePage.cs. Add the following code in this Class.
public class ReportBasePage : System.Web.UI.Page { protected ReportData ReportDataObj { get; set; } protected override void OnInit(EventArgs e) { base.OnInit(e); if (HttpContext.Current != null) if (HttpContext.Current.Session["ReportData"] != null) { ReportDataObj = HttpContext.Current.Session["ReportData"] as ReportData; return; } ReportDataObj = new ReportData(); CaptureRouteData(Page.Request); } private void CaptureRouteData(HttpRequest request) { var mode = (request.QueryString["rptmode"] + "").Trim(); ReportDataObj.IsLocal = mode == "local" ? true : false; ReportDataObj.ReportName = request.QueryString["reportname"] + ""; string dquerystr = request.QueryString["parameters"] + ""; if (!String.IsNullOrEmpty(dquerystr.Trim())) { var param1 = dquerystr.Split(','); foreach (string pm in param1) { var rp = new Parameter(); var kd = pm.Split('='); if (kd[0].Substring(0, 2) == "rp") { rp.ParameterName = kd[0].Replace("rp", ""); if (kd.Length > 1) rp.Value = kd[1]; ReportDataObj.ReportParameters.Add(rp); } else if (kd[0].Substring(0, 2) == "dp") { rp.ParameterName = kd[0].Replace("dp", ""); if (kd.Length > 1) rp.Value = kd[1]; ReportDataObj.DataParameters.Add(rp); } } } } }Add ScriptManager to the ReportView.aspx page. Now Take a Report Viewer to the page. In report viewer set the property AsyncRendering="false". The code is given below.
<rsweb:ReportViewer ID="ReportViewerRSFReports" runat="server" AsyncRendering="false" Width="1271px" Height="1000px" > </rsweb:ReportViewer>Add two NameSpace in ReportView.aspx.cs
using Microsoft.Reporting.WebForms; using System.IO;Change the System.Web.UI.Page to ReportBasePage. Just replace your code using the following.
public partial class ReportView : ReportBasePage { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { RenderReportModels(this.ReportDataObj); } } private void RenderReportModels(ReportData reportData) { RASolarERPData dal = new RASolarERPData(); List<ClosingInventoryValuation> objClosingInventory = new List<ClosingInventoryValuation>(); // Reset report properties. ReportViewerRSFReports.Height = Unit.Parse("100%"); ReportViewerRSFReports.Width = Unit.Parse("100%"); ReportViewerRSFReports.CssClass = "table"; // Clear out any previous datasources. this.ReportViewerRSFReports.LocalReport.DataSources.Clear(); // Set report mode for local processing. ReportViewerRSFReports.ProcessingMode = ProcessingMode.Local; // Validate report source. var rptPath = Server.MapPath(@"./Report/" + reportData.ReportName +".rdlc"); //@"E:\RSFERP_SourceCode\RASolarERP\RASolarERP\Reports\Report\" + reportData.ReportName + ".rdlc"; //Server.MapPath(@"./Report/ClosingInventory.rdlc"); if (!File.Exists(rptPath)) return; // Set report path. this.ReportViewerRSFReports.LocalReport.ReportPath = rptPath; // Set report parameters. var rpPms = ReportViewerRSFReports.LocalReport.GetParameters(); foreach (var rpm in rpPms) { var p = reportData.ReportParameters.SingleOrDefault(o => o.ParameterName.ToLower() == rpm.Name.ToLower()); if (p != null) { ReportParameter rp = new ReportParameter(rpm.Name, p.Value); ReportViewerRSFReports.LocalReport.SetParameters(rp); } } //Set data paramater for report SP execution objClosingInventory = dal.ClosingInventoryReport(this.ReportDataObj.DataParameters[0].Value); // Load the dataSource. var dsmems = ReportViewerRSFReports.LocalReport.GetDataSourceNames(); ReportViewerRSFReports.LocalReport.DataSources.Add(new ReportDataSource(dsmems[0], objClosingInventory)); // Refresh the ReportViewer. ReportViewerRSFReports.LocalReport.Refresh(); } }Add a Folder to the Reports Folder and named it Report. Now add a RDLC report to the Reports/Report folder and named it ClosingInventory.rdlc.
Now add a Controller and Named it ReportController. In to the controller add the following action method.
public ActionResult ReportViewer() { ViewData["reportUrl"] = "../Reports/View/local/ClosingInventory/"; return View(); }Add a view page click on the ReportViewer Controller. Named the view page ReportViewer.cshtml. Add the following code to the view page.
@using (Html.BeginForm("Login")) { @Html.DropDownList("ddlYearMonthFormat", new SelectList(ViewBag.YearMonthFormat, "YearMonthValue", "YearMonthName"), new { @class = "DropDown" }) Stock In Transit: @Html.TextBox("txtStockInTransit", "", new { @class = "LogInTextBox" }) <input type="submit" onclick="return ReportValidationCheck();" name="ShowReport" value="Show Report" /> }Add an Iframe. Set the property of the Iframe as follows
frameborder="0" width="1000"; height="1000"; style="overflow:hidden;" scrolling="no"Add Following JavaScript to the viewer.
function ReportValidationCheck() { var url = $('#hdUrl').val(); var yearmonth = $('#ddlYearMonthFormat').val(); var stockInTransit = $('#txtStockInTransit').val() if (stockInTransit == "") { stockInTransit = 0; } if (yearmonth == "0") { alert("Please Select Month Correctly."); } else { //url = url + "dpSpYearMonth=" + yearmonth + ",rpYearMonth=" + yearmonth + ",rpStockInTransit=" + stockInTransit; url = "../Reports/ReportView.aspx?rptmode=local&reportname=ClosingInventory¶meters=dpSpYearMonth=" + yearmonth + ",rpYearMonth=" + yearmonth + ",rpStockInTransit=" + stockInTransit; var myframe = document.getElementById("ifrmReportViewer"); if (myframe !== null) { if (myframe.src) { myframe.src = url; } else if (myframe.contentWindow !== null && myframe.contentWindow.location !== null) { myframe.contentWindow.location = url; } else { myframe.setAttribute('src', url); } } } return false; }In Web.config file add the following key to the appSettings section add
key="UnobtrusiveJavaScriptEnabled" value="true"In system.web handlers Section add the following key
add
verb="*" path="Reserved.ReportViewerWebControl.axd" type = "Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"Change your data source as your own. This solution is very simple and I think every one enjoy it.
- 在您的解决方案中创建一个文件夹并命名为 Reports。
- 添加一个 ASP.Net Web 表单并将其命名为 ReportView.aspx
创建一个类 ReportData 并将其添加到 Reports 文件夹中。将以下代码添加到类。
public class ReportData { public ReportData() { this.ReportParameters = new List<Parameter>(); this.DataParameters = new List<Parameter>(); } public bool IsLocal { get; set; } public string ReportName { get; set; } public List<Parameter> ReportParameters { get; set; } public List<Parameter> DataParameters { get; set; } } public class Parameter { public string ParameterName { get; set; } public string Value { get; set; } }添加另一个类并将其命名为 ReportBasePage.cs。在这个类中添加以下代码。
public class ReportBasePage : System.Web.UI.Page { protected ReportData ReportDataObj { get; set; } protected override void OnInit(EventArgs e) { base.OnInit(e); if (HttpContext.Current != null) if (HttpContext.Current.Session["ReportData"] != null) { ReportDataObj = HttpContext.Current.Session["ReportData"] as ReportData; return; } ReportDataObj = new ReportData(); CaptureRouteData(Page.Request); } private void CaptureRouteData(HttpRequest request) { var mode = (request.QueryString["rptmode"] + "").Trim(); ReportDataObj.IsLocal = mode == "local" ? true : false; ReportDataObj.ReportName = request.QueryString["reportname"] + ""; string dquerystr = request.QueryString["parameters"] + ""; if (!String.IsNullOrEmpty(dquerystr.Trim())) { var param1 = dquerystr.Split(','); foreach (string pm in param1) { var rp = new Parameter(); var kd = pm.Split('='); if (kd[0].Substring(0, 2) == "rp") { rp.ParameterName = kd[0].Replace("rp", ""); if (kd.Length > 1) rp.Value = kd[1]; ReportDataObj.ReportParameters.Add(rp); } else if (kd[0].Substring(0, 2) == "dp") { rp.ParameterName = kd[0].Replace("dp", ""); if (kd.Length > 1) rp.Value = kd[1]; ReportDataObj.DataParameters.Add(rp); } } } } }将 ScriptManager 添加到 ReportView.aspx 页。现在将报告查看器带到页面。在报告查看器中设置属性 AsyncRendering="false"。代码如下。
<rsweb:ReportViewer ID="ReportViewerRSFReports" runat="server" AsyncRendering="false" Width="1271px" Height="1000px" > </rsweb:ReportViewer>在 ReportView.aspx.cs 中添加两个 NameSpace
using Microsoft.Reporting.WebForms; using System.IO;将 System.Web.UI.Page 更改为 ReportBasePage。只需使用以下内容替换您的代码。
public partial class ReportView : ReportBasePage { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { RenderReportModels(this.ReportDataObj); } } private void RenderReportModels(ReportData reportData) { RASolarERPData dal = new RASolarERPData(); List<ClosingInventoryValuation> objClosingInventory = new List<ClosingInventoryValuation>(); // Reset report properties. ReportViewerRSFReports.Height = Unit.Parse("100%"); ReportViewerRSFReports.Width = Unit.Parse("100%"); ReportViewerRSFReports.CssClass = "table"; // Clear out any previous datasources. this.ReportViewerRSFReports.LocalReport.DataSources.Clear(); // Set report mode for local processing. ReportViewerRSFReports.ProcessingMode = ProcessingMode.Local; // Validate report source. var rptPath = Server.MapPath(@"./Report/" + reportData.ReportName +".rdlc"); //@"E:\RSFERP_SourceCode\RASolarERP\RASolarERP\Reports\Report\" + reportData.ReportName + ".rdlc"; //Server.MapPath(@"./Report/ClosingInventory.rdlc"); if (!File.Exists(rptPath)) return; // Set report path. this.ReportViewerRSFReports.LocalReport.ReportPath = rptPath; // Set report parameters. var rpPms = ReportViewerRSFReports.LocalReport.GetParameters(); foreach (var rpm in rpPms) { var p = reportData.ReportParameters.SingleOrDefault(o => o.ParameterName.ToLower() == rpm.Name.ToLower()); if (p != null) { ReportParameter rp = new ReportParameter(rpm.Name, p.Value); ReportViewerRSFReports.LocalReport.SetParameters(rp); } } //Set data paramater for report SP execution objClosingInventory = dal.ClosingInventoryReport(this.ReportDataObj.DataParameters[0].Value); // Load the dataSource. var dsmems = ReportViewerRSFReports.LocalReport.GetDataSourceNames(); ReportViewerRSFReports.LocalReport.DataSources.Add(new ReportDataSource(dsmems[0], objClosingInventory)); // Refresh the ReportViewer. ReportViewerRSFReports.LocalReport.Refresh(); } }将文件夹添加到报告文件夹并将其命名为报告。现在将 RDLC 报告添加到 Reports/Report 文件夹并将其命名为 ClosingInventory.rdlc。
现在添加一个控制器并将其命名为 ReportController。在控制器中添加以下操作方法。
public ActionResult ReportViewer() { ViewData["reportUrl"] = "../Reports/View/local/ClosingInventory/"; return View(); }添加视图页面单击 ReportViewer 控制器。将视图页面命名为 ReportViewer.cshtml。将以下代码添加到查看页面。
@using (Html.BeginForm("Login")) { @Html.DropDownList("ddlYearMonthFormat", new SelectList(ViewBag.YearMonthFormat, "YearMonthValue", "YearMonthName"), new { @class = "DropDown" }) Stock In Transit: @Html.TextBox("txtStockInTransit", "", new { @class = "LogInTextBox" }) <input type="submit" onclick="return ReportValidationCheck();" name="ShowReport" value="Show Report" /> }添加 iframe。设置iframe的属性如下
frameborder="0" width="1000"; height="1000"; style="overflow:hidden;" scrolling="no"向查看器添加以下 JavaScript。
function ReportValidationCheck() { var url = $('#hdUrl').val(); var yearmonth = $('#ddlYearMonthFormat').val(); var stockInTransit = $('#txtStockInTransit').val() if (stockInTransit == "") { stockInTransit = 0; } if (yearmonth == "0") { alert("Please Select Month Correctly."); } else { //url = url + "dpSpYearMonth=" + yearmonth + ",rpYearMonth=" + yearmonth + ",rpStockInTransit=" + stockInTransit; url = "../Reports/ReportView.aspx?rptmode=local&reportname=ClosingInventory¶meters=dpSpYearMonth=" + yearmonth + ",rpYearMonth=" + yearmonth + ",rpStockInTransit=" + stockInTransit; var myframe = document.getElementById("ifrmReportViewer"); if (myframe !== null) { if (myframe.src) { myframe.src = url; } else if (myframe.contentWindow !== null && myframe.contentWindow.location !== null) { myframe.contentWindow.location = url; } else { myframe.setAttribute('src', url); } } } return false; }在 Web.config 文件中,将以下键添加到 appSettings 部分添加
key="UnobtrusiveJavaScriptEnabled" value="true"在 system.web handlers 部分添加以下键
添加
verb="*" path="Reserved.ReportViewerWebControl.axd" type = "Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"将您的数据源更改为您自己的。这个解决方案非常简单,我想每个人都喜欢它。
回答by kingdango
You can use the ReportViewer object to render an RDLC to PDF or HTML. For my case (below) I wanted a PDF document and I returned it as a FileContentResult ActionResult. If you want it to return as a download use the File ActionResult (I've commented that out for your use).
您可以使用 ReportViewer 对象将 RDLC 呈现为 PDF 或 HTML。对于我的情况(如下),我想要一个 PDF 文档,并将其作为 FileContentResult ActionResult 返回。如果您希望它作为下载返回,请使用 File ActionResult (我已将其注释掉以供您使用)。
public ActionResult GetPackingSlipPDF(int shipmentId)
{
var shipment = _inboundShipmentService.GetInboundShipmentById(shipmentId);
Warning[] warnings;
string mimeType;
string[] streamids;
string encoding;
string filenameExtension;
var viewer = new ReportViewer();
viewer.LocalReport.ReportPath = @"Labels\PackingSlip.rdlc";
var shipLabel = new ShippingLabel { ShipmentId = shipment.FBAShipmentId, Barcode = GetBarcode(shipment.FBAShipmentId) };
viewer.LocalReport.DataSources.Add(new ReportDataSource("ShippingLabel", new List<ShippingLabel> { shipLabel }));
viewer.LocalReport.Refresh();
var bytes = viewer.LocalReport.Render("PDF", null, out mimeType, out encoding, out filenameExtension, out streamids, out warnings);
return new FileContentResult(bytes, mimeType);
//return File(bytes, mimeType, shipment.FBAShipmentId + "_PackingSlip.pdf");
}
回答by Peter
I put this project together ages ago http://mvcrdlc.codeplex.com/
我很久以前就把这个项目放在一起http://mvcrdlc.codeplex.com/
From memory there should be an html render of the rdlc as well as the PDF
从内存中应该有 rdlc 和 PDF 的 html 渲染

