我有以下代码:
Response.ClearContent();
Response.AddHeader( "Content-type", "application/vnd.ms-excel");
Response.AddHeader("content-disposition", "attachment;filename=test.xls");
Response.ContentType = "application/excel";
var swr = new StringWriter();
var tw = new HtmlTextWriter(swr);
grd.RenderControl(tw);
Response.Write(swr.ToString());
Response.Flush();
Response.End();
tw.Close();
swr.Close();
此操作由以下jquery代码触发:
<img src="../../../../Content/images/Excel-icon.png"
onclick = "alert ($('#Filter').serialize());
$.ajax({
type: 'POST',
url: '<%=Url.Action( "Excel") %>',
data: $('#Filter').serialize(),
success : function (data, textStatus, jqXHR)
{ alert (data);},
error: function (jqXHR, textStatus, errorThrown)
{ alert (textStatus + ' ' + errorThrown);}
});" />
我已经向fiddler确认标头具有预期值。我也可以使用Web View查看fiddler中的数据。
此外,当我显示成功函数中的数据内容时,它具有我尝试导出到excel的表的原始html。
提前感谢您的帮助。
答案 0 :(得分:5)
哦,不,你不能用AJAX下载文件。执行AJAX调用,将文件流式传输到客户端,执行成功回调并传递文件的内容,这样您就会陷入困境。出于明显的安全原因,您无法对此数据做多少工作。您无法将其保存到客户端计算机。您无法在此阶段显示“另存为”提示。
因此,请删除您的javascript AJAX调用,并使用正常的GET或POST请求调用您的控制器操作。
答案 1 :(得分:3)
我建议不要将该代码直接放在Action方法中 - 这不是一种非常干净的方式来使用MVC,你肯定无法从AJAX请求中触发文件下载。
您可以从ExcelResult
类派生新的操作结果 - 称之为FileResult
,覆盖其ExecuteResult
方法以强制将内容导入Response
。
按钮单击应该只是通过链接点击操作(导航到它)。服务器和浏览器的响应将协同工作,强制用户无需浏览新页面。
示例:
public class ExcelResult : FileResult
{
public override void ExecuteResult(ControllerContext context)
{
string file;
using (var swr = new StringWriter())
{
using (var tw = new HtmlTextWriter(swr))
{
// Not sure where your grd object comes from
grd.RenderControl(tw);
file = swr.ToString();
}
}
var response = context.HttpContext.Response;
response.Buffer = true;
response.Clear();
response.ClearHeaders();
response.ContentType = "application/excel";
response.CacheControl = "public";
response.AddHeader("Pragma", "Public");
response.AddHeader("Expires", "0");
response.AddHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.AddHeader("Content-Description", "describe your file");
response.AddHeader("Content-Disposition","attachment; filename=excel.xls");
response.Write(file);
response.Flush();
response.End();
}
}
你的行动很简单:
public ExcelResult Excel()
{
return new ExcelResult(/* whatever you need to pass */);
}