在来自 ASP.NET MVC 的 JQuery-AJAX 请求中下载 excel 文件
Download an excel file in JQuery-AJAX request from ASP.NET MVC
在我的 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下载文件,但您可以使用window.location
和AJAX下载文件来制作下载的文件。我的意思是,如果您使用 AJAX GET/POST,所有文件内容都将在浏览器的内存中,但无法保存到磁盘(因为 JavaScript 限制)。
相反,您可以使用 window.location
指向 URL,后者将获取文件并提示 save/open 提示符。或者您可以使用隐藏的 iFrame
并将 iFrame 的 src
属性设置为 URL 将从中下载文件。
为什么不呢?
ramiramilu 关于使用 window.location
和 iframe
的说法是正确的。
除了 ASP.NET MVC3,我做了同样的事情。
我建议使用 returns FileContentResult
的控制器
仅供参考 FileContentResult
MSDN
最后我是怎么做到的(控制器):
[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);
}
}
});
顺便说一句,我删除了所有异常处理程序以简化代码,但我认为您可以自己完成。
在我的 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下载文件,但您可以使用window.location
和AJAX下载文件来制作下载的文件。我的意思是,如果您使用 AJAX GET/POST,所有文件内容都将在浏览器的内存中,但无法保存到磁盘(因为 JavaScript 限制)。
相反,您可以使用 window.location
指向 URL,后者将获取文件并提示 save/open 提示符。或者您可以使用隐藏的 iFrame
并将 iFrame 的 src
属性设置为 URL 将从中下载文件。
为什么不呢?
ramiramilu 关于使用 window.location
和 iframe
的说法是正确的。
除了 ASP.NET MVC3,我做了同样的事情。
我建议使用 returns FileContentResult
仅供参考 FileContentResult
MSDN
最后我是怎么做到的(控制器):
[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);
}
}
});
顺便说一句,我删除了所有异常处理程序以简化代码,但我认为您可以自己完成。