【问题标题】:Download an excel file in JQuery-AJAX request from ASP.NET MVC从 ASP.NET MVC 下载 JQuery-AJAX 请求中的 excel 文件
【发布时间】:2015-01-10 08:37:48
【问题描述】:

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

它在非 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();

现在我正在尝试通过 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 () {
                }
            });

我怎样才能完成它? 提前谢谢你。

【问题讨论】:

  • 您不需要 AJAX 调用来执行此操作。
  • @king.code 我想在 ajax 响应中做。
  • 然后看看this。它是 PHP,但我猜是这样的。

标签: jquery ajax asp.net-mvc download closedxml


【解决方案1】:

为什么不呢? ramiramilu 使用window.locationiframe 是对的。 我做了同样的事情,但对于 ASP.NET MVC3。

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

仅供参考FileContentResultMSDN

最后我是怎么做到的(控制器):

    [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");
    }

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

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);
                }
            }
        });

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

【讨论】:

  • 你能告诉我“fileHolder”是做什么用的吗?
  • iframe 的 ID。使用同一窗口的目的。
  • statusCode 部分解决了我的问题,因为它没有成功。谢谢。
  • 我是否需要添加任何参考才能在 MVC5 中获取 XlWorkbook?
  • 当然。您可以转到有关 closedXML 的问题中的链接
【解决方案2】:

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

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

【讨论】:

  • 阅读@king.code 对 OP 的评论。 AJAX 请求是可能的,他引用了一个示例。这解决了我的问题,是的,如果您发现需要,可以使用 AJAX 下载文件。
  • @jaredbaszler,如果您查看 king.code 帖子,即使他们使用了 window.location。你能清楚地解释投票背后的原因吗?
  • 因为您在上面的第一句话中明确指出“您无法使用 AJAX 下载文件”。正如您稍后在自己的帖子中所说的那样,这是不正确的。乍一看,由于您提出论点的方式,我打算寻找另一种选择。谢天谢地,我阅读了上面@king.code 的回复并找到了我想要的东西。从技术上讲,您不通过 AJAX 下载是正确的,但我想通过使用 window.location 来利用 AJAX 的其他功能。你提出论点的方式让我认为这是不可能的。
  • 同意你的观点,在这种情况下,编辑会使答案的本质更合适,而不是将整个答案投射为错误的。
猜你喜欢
  • 2012-11-06
  • 1970-01-01
  • 2015-08-22
  • 1970-01-01
  • 2011-10-16
  • 1970-01-01
  • 2014-07-03
  • 2019-10-25
  • 1970-01-01
相关资源
最近更新 更多