从 ASP.NET MVC 下载 JQuery-AJAX 请求中的 excel 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27874360/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 11:27:57  来源:igfitidea点击:

Download an excel file in JQuery-AJAX request from ASP.NET MVC

jqueryajaxasp.net-mvcdownloadclosedxml

提问by s.k.paul

In my ASP.NET MVC project, I generated a excel file using ClosedXML.

在我的 ASP.NET MVC 项目中,我使用ClosedXML生成了一个 excel 文件。

It works well in non-ajax call. Here is my controller action method

它在非 ajax 调用中运行良好。这是我的控制器操作方法

 // Prepare the response
 Response.Clear();
 Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
 Response.AddHeader("content-disposition", "attachment;filename=\"" + reportHeader + ".xlsx\"");

 // Flush the workbook to the Response.OutputStream
 using (MemoryStream memoryStream = new MemoryStream())
 {
     MyWorkBook.SaveAs(memoryStream);
     memoryStream.WriteTo(Response.OutputStream);
     memoryStream.Close();
 }
 Response.End();

Now I am trying to do it via an ajax request. But the file is not sent from mvc controller.

现在我正在尝试通过 ajax 请求来做到这一点。但是该文件不是从 mvc 控制器发送的。

$.ajax({
                url: url,
                type: "POST",
                data: fd,
                processData: false,  
                contentType: false,  
                beforeSend: function () {
                },
                success: function (response) {

                },
                error: function (request, status, error) {
                },
                complete: function () {
                }
            });

How can i accomplish it? Thank you in advance.

我怎样才能完成它?先感谢您。

回答by SouXin

Why not? ramiramilu was right about using window.locationand iframe. I did the same thing but for ASP.NET MVC3.

为什么不?ramiramilu 关于使用window.locationand是正确的iframe。我做了同样的事情,但对于 ASP.NET MVC3。

I would suggest to use controller which returns FileContentResult

我建议使用返回的控制器 FileContentResult

FYI about FileContentResultMSDN

仅供参考FileContentResultMSDN

And finally how I did it (Controller):

最后我是如何做到的(控制器):

    [HttpPost]
    public HttpStatusCodeResult CreateExcel()
    {
        XLWorkbook wb = new XLWorkbook(XLEventTracking.Disabled); //create Excel

        //Generate information for excel file
        // ...

        if (wb != null)
        {
            Session["ExcelResult"] = wb;
            return new HttpStatusCodeResult(HttpStatusCode.OK);
        }

        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);

    }

    [HttpGet]
    public FileContentResult ExcelResult(string reportHeader) //it's your data passed to controller
    {

        byte[] fileBytes = GetExcel((XLWorkbook)Session["ExcelResult"]);
        return File(fileBytes, MediaTypeNames.Application.Octet, reportHeader + ".xlsx");
    }

In model (you can remove static if you wish, and call it with instance)

在模型中(如果你愿意,你可以删除静态,并用实例调用它)

public static byte[] GetExcel(XLWorkbook wb)
{
    using (var ms = new MemoryStream())
    {
        wb.SaveAs(ms);
        return ms.ToArray();
    }
}

AJAX:

阿贾克斯:

$.ajax({
            url: "@Url.Action("CreateExcel")",
            async: true,
            type: "POST",
            traditional: true,
            cache: false,
            statusCode: {
                400: function () {
                    alert("Sorry! We cannot process you request");
                },
                200: function () {
                    $("#fileHolder")
                    .attr('src', 
                    '@Url.Action("ExcelResult")?reportHeader=' + 
                    reportHeader);
                }
            }
        });

BTW, I removed all exception handlers to simplify the code, but I assume You can do it yourself.

顺便说一句,我删除了所有异常处理程序以简化代码,但我认为您可以自己完成。

回答by ramiramilu

You cannot DIRECTLYdownload a file using AJAX, but you can download a file using window.locationin conjunction with AJAX to make the file downloaded. What I mean is that if you use AJAX GET/POST all the file content will be in memory of the browser but cannot be saved to disk (because of JavaScript limitations).

您不能直接使用 AJAX 下载文件,但可以window.location与 AJAX 结合使用下载文件以下载文件。我的意思是,如果您使用 AJAX GET/POST,所有文件内容都将在浏览器的内存中,但无法保存到磁盘(由于 JavaScript 限制)。

Instead you can use window.locationto point to a URL which in turn will fetch the file and prompt the save/open prompt. Or else you can use a hidden iFrameand set the srcattribute of iFrame with the URL from which will download the file.

相反,您可以使用window.location指向一个 URL,该 URL 将获取文件并提示保存/打开提示。或者,您可以使用 hiddeniFrame并使用src将从下载文件的 URL设置iFrame的属性。