我有一个控制器动作来使用通过AJAX从客户端发送的过滤数据创建一个DataTable,它本身可以正常工作:
[HttpPost]
public JsonResult RetrieveStaffData(FilterModel jsonData)
{
var data = (from i in db.StaffList
where i.Username.Contains(jsonData.Username)
&& i.Surname.Contains(jsonData.Surname)
&& i.Forename.Contains(jsonData.Forename)
// etc...
orderby i.Surname ascending)
.ToList();
if (data == null)
return Json(new { success = "False", message = "filter brought back no results" });
DataExport(ToDataTable(data));
return Json(new { success = "True", message = "data retreival successful" });
}
我还有一个现有的DataExport控制器操作,它将DataTable转换为excel文档并将其发送到客户端进行下载,其本身也可以正常工作:
public void DataExport(DataTable dt)
{
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=spreadsheetname.xlsx");
using (var p = new ExcelPackage())
{
var ws = p.Workbook.Worksheets.Add("StaffList");
ws.Cells.LoadFromDataTable(dt, true);
ws.Cells.AutoFitColumns();
var ms = new System.IO.MemoryStream();
p.SaveAs(ms);
ms.WriteTo(Response.OutputStream);
}
Response.OutputStream.Flush();
Response.OutputStream.Close();
Response.End();
}
问题在于,在return
之前调用DataExport操作时,文件作为AJAX响应而不是文件下载发送到客户端,文件下载在响应中显示为乱码二进制文件。
如何向客户端发送响应消息,然后发送文件以供下载? Async / Await会在这里提供帮助吗?我想我可以在JS中使用Blob来处理文件客户端,但只是想知道是否有更好的方法来实现它。
提前感谢您提供的任何帮助。
答案 0 :(得分:1)
您必须让客户端发出辅助请求,而不是通过ajax - 您无法通过ajax下载文件。使用类似window.open的内容,定向到下载操作方法的URL,该方法运行导出方法。
我不知道您是如何编写ajax请求的,但是在回调中表示响应成功,请执行以下操作:
window.open(@Url.Action("DownloadData"));
查看你的代码也是可能的,你根本不需要ajax请求 - 它似乎返回的只是一个“是/否”类型的响应。也许该页面应该只是直接打开“下载”操作的窗口,这将运行查询,然后运行DataExport函数。