简体   繁体   English

MVC流输出到HTML div

[英]MVC Stream outputting to HTML div

Small problem here with an MVC app that I'm not sure how to figure out a way around. 这里是MVC应用程序的一个小问题,我不确定该如何解决。

Basically, I'm adding additional functionality to a system that was originally created by someone else (c#). 基本上,我要向最初由其他人(c#)创建的系统添加其他功能。 For a reporting system, the results were only ever displayed on screen. 对于报告系统,结果仅显示在屏幕上。 Now I am building in the functionality to allow the user the ability to download their report as an Excel document. 现在,我正在构建该功能,以允许用户将其报告下载为Excel文档。

So basically, I have a view that displays the date ranges, and some other search refinement options to the user. 因此,基本上,我有一个向用户显示日期范围和其他一些搜索优化选项的视图。 I have introduced a radio button that if selected will download the report as opposed to displaying it on screen. 我介绍了一个单选按钮,如果选中该按钮,将下载报告,而不是在屏幕上显示报告。

Here are my three actions within the ReportController: 这是我在ReportController中执行的三个操作:

    public ActionResult Index()
    {
        return View();
    }


    public ActionResult ProductReport(AdminReportRequest reportRequest, FormCollection formVariables)
    {
        AdminEngine re = new AdminEngine();

        if (!reportRequest.Download)
        {
            AdminReport report = re.GetCompleteAdminReport(reportRequest);

            return View(report);
         }

            Stream ExcelReport = re.GetExcelAdminReport(reportRequest);
            TempData["excelReport"] = ExcelReport;

        return RedirectToAction("ExcelProductReport");

       }

    public FileResult ExcelReport()
    {
        var ExcelReport = TempData["excelReport"] as Stream;

        return new FileStreamResult(ExcelReport, "application/ms-excel")
        {
            FileDownloadName = "Report" + DateTime.Now.ToString("MMMM d, yyy") + ".xls"
        }; 
    } 

I've debugged through the AdminEngine, and everything looks fine. 我已经通过AdminEngine进行了调试,一切看起来都很好。 However, in the ExcelReport action, when it comes to returning the file - it doesn't. 但是,在ExcelReport动作中,要返回文件-不会。 What I see is a lot of characters on screen (in the 'panelReport' div - see below), mixed in with what would be the data in the excel file. 我看到的是屏幕上有很多字符(在“ panelReport” div中-见下文),与excel文件中的数据混合在一起。

I think I have established that the reason it is being displayed on screen is as a result of some code 我想我已经确定它在屏幕上显示的原因是某些代码的结果

that was written in the Index view: 在“索引”视图中编写的:

<% using (Ajax.BeginForm("ProductReport", "Report", null,
                      new AjaxOptions
                      {
                          UpdateTargetId = "panelReport",
                          InsertionMode = InsertionMode.Replace,
                          OnSuccess = "pageLoaded",
                          OnBegin = "pageLoading",
                          OnFailure = "pageFailed",
                          LoadingElementId = ""
                      },
                      new { id = "SearchForm" })) %>

As you can see, the Ajax.BeginForm statement states that it should update to the panelReport div - which is what it's doing (through the Product Report partial view). 如您所见,Ajax.BeginForm语句指出它应该更新为panelReport div-这就是它所做的(通过Product Report部分视图)。 While this is perfect for when the reports need to be displayed on screen, it is obviously not going to work with an excel file. 虽然这非常适合需要在屏幕上显示报告的情况,但显然它不适用于excel文件。

Is there a way of working around this issue without changing the existing code too much? 有没有解决此问题的方法,而无需过多更改现有代码?

Here is the class where I do the workings for the excel file in case it's required to shed light on the situation: 如果需要了解情况,这是我处理excel文件的类:

Report Class: 报告类别:

public Stream GetExcelAdminReport(AdminReportRequest reportRequest)
{
        AdminReport report = new AdminReport();
        string dateRange = null;
        List<ProductSale> productSales = GetSortedListOfProducts(reportRequest, out dateRange);

        report.DateRange = dateRange;

        if (productSales.Count > 0)
        {
            report.HasData = true;

            CustomisedSalesReport CustSalesRep = new CustomisedSalesReport();

            Stream SalesReport = CustSalesRep.GenerateCustomisedSalesFile(productSales);

            return SalesReport;
        }
}

Workings Class: 工种:

public class CustomisedSalesReport
{
    public Stream GenerateCustomisedSalesFile(List<ProductSale> productSales)
    {
        MemoryStream ms = new MemoryStream();
        HSSFWorkbook templateWorkbook = new HSSFWorkbook();

        HSSFSheet sheet = templateWorkbook.CreateSheet("Sales Report");

        //Workings

        templateWorkbook.Write(ms);
        ms.Position = 0;

        return ms;
    }
} 

The problem is pretty obvious that you are using an Ajax Form to download a file. 这个问题非常明显,因为您正在使用Ajax表单下载文件。 On top you are using the built-in Microsoft Ajax libraries, which seem to be not intelligent enough. 最重要的是,您正在使用内置的Microsoft Ajax库,该库似乎还不够智能。

I can provide 2 solutions: 我可以提供2个解决方案:

  1. The easiest solution (which I have used in the past) is that instead of streaming a file yourself, create an excel file and save it on the server and then send the download link to the user. 最简单的解决方案(我过去使用过)是,您自己创建一个excel文件并将其保存在服务器上,然后将下载链接发送给用户,而不是自己亲自传输文件。 It won't require a lot of change to the code. 它不需要对代码进行大量更改。

  2. You could handle the OnSubmit event of the AjaxForm, see if you it's a file to download. 您可以处理AjaxForm的OnSubmit事件,看看它是否是要下载的文件。 If yes, then make a full postback request (using $.post() ). 如果是,则发出完整的回发请求(使用$.post() )。 This way the browser will automatically pop-up the dialog asking for where to download. 这样,浏览器将自动弹出对话框,询问下载位置。

Hope it makes sense. 希望有道理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM