13

我想在 ASP.NET MVC 项目中以 HTML 格式呈现 RDLC 报告。

在本文的帮助下,我成功制作了一个原型,可以在 PDF、Excel 和 TIFF 图像中呈现 RDLC 报告。但令我惊讶的是,HTML 不是LocalReport.Render().

我遇到了这篇文章,它描述了一个启用 HTML4.0 呈现格式的技巧,但我认为这只是一个ReportViewer控件(虽然我可能是错的)。

问题是,在 MVC 中,如何像 aReportView一样在 HTML 中呈现 RDLC 报告(参见下面的屏幕截图)?

在 ReportView 控件中呈现的 RDLC 报告

4

2 回答 2

17

这是一个简单的任务。您可以按照以下步骤操作。

  1. 在您的解决方案中创建一个文件夹并命名为 Reports。
  2. 添加一个 ASP.Net Web 表单并将其命名为 ReportView.aspx
  3. 创建一个类 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; }
    }
    
  4. 添加另一个类并将其命名为 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);
                    }
                }
            }
        }
    }
    
  5. 将 ScriptManager 添加到 ReportView.aspx 页面。现在将报表查看器带到该页面。在报表查看器中设置属性 AsyncRendering="false"。代码如下。

    <rsweb:ReportViewer ID="ReportViewerRSFReports" runat="server" AsyncRendering="false"
        Width="1271px" Height="1000px" >
    </rsweb:ReportViewer>
    
  6. 在 ReportView.aspx.cs 中添加两个 NameSpace

    using Microsoft.Reporting.WebForms;
    using System.IO;
    
  7. 将 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();
        }
    }
    
  8. 将文件夹添加到报告文件夹并将其命名为报告。现在将 RDLC 报告添加到 Reports/Report 文件夹并将其命名为 ClosingInventory.rdlc。

  9. 现在添加一个控制器并将其命名为 ReportController。在控制器中添加以下操作方法。

    public ActionResult ReportViewer()
    {                
        ViewData["reportUrl"] = "../Reports/View/local/ClosingInventory/";
    
        return View();
    }
    
  10. 在 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" />
    
      }
    
  11. 添加一个 iframe。设置iframe的属性如下

    frameborder="0"  width="1000"; height="1000"; style="overflow:hidden;" scrolling="no"
    
  12. 将以下 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&parameters=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;
    }
    
  13. 在 Web.config 文件中,将以下键添加到 appSettings 部分添加

    key="UnobtrusiveJavaScriptEnabled" value="true"
    
  14. 在 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"

  15. 将您的数据源更改为您自己的。这个解决方案非常简单,我想每个人都喜欢它。

于 2013-04-05T09:11:55.210 回答
8

您可以使用 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");
    }
于 2012-05-30T17:21:06.383 回答