在动态创建PDF之前显示加载屏幕

时间:2014-03-07 20:44:15

标签: c# asp.net-mvc pdf

我有一个观点,即返回动态创建的PDF,然后在新标签中显示PDF,而不是返回View()。我不是在任何地方保存PDF或将其存储在任何地方。我想要做的是在创建PDF时显示加载屏幕。可以这样做吗?

public ActionResult SolicitorActionReport_Load(SolicitorActionParamsViewModel viewModel) {
    var cultivationModel = new CultivationModel(viewModel, ConstituentRepository, CampaignRepository);
    var cultivationData = cultivationModel.GetCultivationActivityData();
    var reportParamModel = new List<ReportParamModel>
                                   {new ReportParamModel {AgencyName = SelectedUserAgency.AgencyName, StartDate = viewModel.StartDate, EndDate = viewModel.EndDate}};

    var reportToRun = "ActionDateCultivationReport";
    if (viewModel.SortActionBy == SolicitorActionReportSortType.Constituent) {
        reportToRun = "ConstituentCultivationReport";
    } else if (viewModel.SortActionBy == SolicitorActionReportSortType.Solicitor) {
        reportToRun = "SolicitorCultivationReport";
    }

    return FileContentPdf("Constituent", reportToRun, cultivationData, reportParamModel, new List<FundraisingAppealMassSummary>(), new List<FundraisingAppealPortfolioSummary>());
}



public FileContentResult FileContentPdf(string folder, string reportName, object dataSet,object reportParamModel,object appealMassDataSet, object appealPortfolioDataSet) {
    var localReport = new LocalReport();
    localReport.ReportPath = Server.MapPath("~/bin/Reports/" + folder + "/rpt" + reportName + ".rdlc");
    var reportDataSource = new ReportDataSource(reportName + "DataSet", dataSet);

    var reportParamsDataSource = new ReportDataSource("ReportParamModelDataSet", reportParamModel);
    var reportParamsDataSourceMass = new ReportDataSource("FundraisingAppealMassSummaryDataSet", appealMassDataSet);
    var reportParamsDataSourcePortfolio = new ReportDataSource("FundraisingAppealPortfolioSummaryDataSet", appealPortfolioDataSet);

    #region Setting ReportViewControl

    localReport.DataSources.Add(reportDataSource);
    localReport.DataSources.Add(reportParamsDataSource);
    localReport.DataSources.Add(reportParamsDataSourceMass);
    localReport.DataSources.Add(reportParamsDataSourcePortfolio);

    localReport.SubreportProcessing += (s, e) => { e.DataSources.Add(reportDataSource); };

    string reportType = "pdf";
    string mimeType;
    string encoding;
    string fileNameExtension;
    //The DeviceInfo settings should be changed based on the reportType             
    //http://msdn2.microsoft.com/en-us/library/ms155397.aspx             
    string deviceInfo = "<DeviceInfo><OutputFormat>PDF</OutputFormat></DeviceInfo>";
    Warning[] warnings;
    string[] streams;
    byte[] renderedBytes;
    //Render the report             
    renderedBytes = localReport.Render(reportType, deviceInfo, out mimeType, out encoding, out fileNameExtension, out streams, out warnings);

    #endregion

    return File(renderedBytes, mimeType);
}

2 个答案:

答案 0 :(得分:5)

  

我没有在任何地方保存PDF或将其存储在任何地方。我想要做的是在创建PDF时显示加载屏幕。可以这样做吗?

简答

,不在新标签页中。


您尝试做的主要问题是在控制浏览器方面缺乏力量。具体来说,当您告诉锚点在新选项卡中打开其超链接时(即target="_blank")。有一些常见的方法通常会让用户感到沮丧,因为你正在改变他们可能依赖/依赖的行为。

解决方法

使用此jQuery File Download pluginview a demo),您可以非常接近所需的结果。基本上,它操纵iframe来排队下载。这样就可以显示加载div,同时还可以将用户保留在活动页面上(而不是将用户指向另一个选项卡)。然后,用户可以单击下载的PDF,该PDF最有可能在新选项卡中打开(查看兼容的浏览器here)。


如果您决定使用此插件,请执行以下步骤:

  1. Download插件js来源并将其包含在您的Scripts中。
  2. 包含插件MVC Demo中提供的FileDownloadAttribute类:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 
    public class FileDownloadAttribute: ActionFilterAttribute
    {
        public FileDownloadAttribute(string cookieName = "fileDownload", string cookiePath = "/")
        {
            CookieName = cookieName;
            CookiePath = cookiePath;
        }
    
        public string CookieName { get; set; }
    
        public string CookiePath { get; set; }
    
        /// <summary>
        /// If the current response is a FileResult (an MVC base class for files) then write a
        /// cookie to inform jquery.fileDownload that a successful file download has occured
        /// </summary>
        /// <param name="filterContext"></param>
        private void CheckAndHandleFileResult(ActionExecutedContext filterContext)
        {
            var httpContext = filterContext.HttpContext;
            var response = httpContext.Response;
    
            if (filterContext.Result is FileResult)
                //jquery.fileDownload uses this cookie to determine that a file download has completed successfully
                response.AppendCookie(new HttpCookie(CookieName, "true") { Path = CookiePath });
            else
                //ensure that the cookie is removed in case someone did a file download without using jquery.fileDownload
                if (httpContext.Request.Cookies[CookieName] != null)
                {
                    response.AppendCookie(new HttpCookie(CookieName, "true") { Expires = DateTime.Now.AddYears(-1), Path = CookiePath });
                }
        }
    
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            CheckAndHandleFileResult(filterContext);
    
            base.OnActionExecuted(filterContext);
        }
    }
    

    <子> github source

  3. FileDownload属性应用于ActionResult方法:

    [FileDownload]
    public ActionResult SolicitorActionReport_Load(SolicitorActionParamsViewModel viewModel) {
        ...
    
        return FileContentPdf("Constituent", reportToRun, cultivationData, reportParamModel, new List<FundraisingAppealMassSummary>(), new List<FundraisingAppealPortfolioSummary>());
    }
    
  4. 在您要链接到报告的View中添加必要的标记:

    <a class="report-download" href="/Route/To/SolicitorActionReport">Download PDF</a>
    
  5. 将事件处理程序附加到report-download锚点:

    $(document).on("click", "a.report-download", function () {
        $.fileDownload($(this).prop('href'), {
            preparingMessageHtml: "We are preparing your report, please wait...",
            failMessageHtml: "There was a problem generating your report, please try again."
        });
        return false; //this is critical to stop the click event which will trigger a normal file download!
    });
    
  6. 您可以在http://jqueryfiledownload.apphb.com/查看工作演示。还有一个演示使用预先设置的jQuery UI模式来“美化”用户体验。

    您还可以从johnculviner / jquery.fileDownload github下载演示ASP.NET MVC解决方案,以查看所有这些工作。

答案 1 :(得分:0)

我认为你有两个选择:

  1. 使用精美的GIF微调器重定向到“加载”页面,然后将请求定向到PDF(如果PDF需要一点服务器时间生成,这将有效 - 访问者将在等待下一个页面时查看加载页面页面加载)
    1. 使用iFrame:加载包含iframe的网页。当iFrame加载PDF本身时,此页面可以覆盖旋转的GIF和加载消息。注意:您可以使iframe 100%宽度和高度