2011-12-05 29 views
1

我有一塊通過發送和數組和一個int的JavaScript。MVC JavaScript方法調用不會啓動excel保存對話框

var InvoicesAndId = { values: indexArray, Id:3 }; 

$.ajax({ 
type: "POST", 
url: 'Invoice/Export', 
data: postData, 
success: function (data) {location.replace(window.location.pathname); }, 
dataType: "json", 
tradional: true 
}); 

所以這個呼籲我的控制器的方法:

public void Export(InvoicesAndId invoicesAndId) 
{ 
... 

Response.AppendHeader("content-disposition", "attachment; filename" + "invoices.csv"); 
Response.ContentType = "application/ms-excel"; 
Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8"); 
Response.Write("word"); 
Response.End(); 
} 

所以與調試我發現,InvoicesAndId正確填充。問題是一個對話框應該出現是否打開或保存excel文件。

這沒有發生。

我知道這與我如何調用函數有關,因爲如果我用ActionLink調用它,對話框會出現。

我在做什麼錯?這與ajax調用有關嗎?

如何解決這個問題?我無法使用ActionLink,因爲不可能有方法來填充參數。

+0

我不明白這一點。你爲什麼改變接受的答案?你的問題不是關於MVC ActionResult,而是關於JavaScript。 Darin的回答很好,我也贊成。我的回答不正確或無用嗎?我錯過了什麼嗎? –

回答

3

我在做什麼錯?

在ASP.NET MVC你平時調用它返回的ActionResult控制器動作,他們不使用Response.Write

public ActionResult Export(InvoicesAndId invoicesAndId) 
{ 
    Response.ContentType = "application/ms-excel"; 
    byte[] excel = Encoding.UTF8.GetBytes("word"); // Obviously not a valid Excel 
    return File(excel, "application/ms-excel", "invoices.csv"); 
} 

現在很明顯的內容類型設置爲"application/ms-excel"續寫simlpe字符串,如word到答覆,不要指望得到任何東西,但腐敗的Excel文件。但我想這只是一個例子,您將修復並編寫一個真正的Excel文件。

或調整的內容類型爲CSV,如果這是你打算送什麼:

Response.ContentType = "text/csv"; 

現在,這僅僅是第一部分。第二部分和實際存在問題根源的部分是您正在使用AJAX調用此控制器操作。您不能使用AJAX調用應該下載文件的控制器操作。只是因爲當你使用AJAX來調用這樣一個動作時,你最終會在調用data javascript變量幷包含CSV文件的成功回調中結束。顯然,既然你現在在客戶端,你無法做任何事情。出於安全原因,您不能將其保存到客戶端,也不能提示下載(它已經下載)。

因此,您應該使用標準鏈接或表單提交來調用應該將流式文件下載到的控制器操作。

2

您不必使用$ .ajax,您可以使用$.param()序列化您的參數並將位置設置爲構造的url;

var InvoicesAndId = { values: indexArray, Id:3 }; 
location.href = 'Invoice/Export?' + $.param(InvoicesAndId, true); 

這樣,瀏覽器將嘗試導航到新的URL,而是因爲它返回一個文件,文件打開/保存對話框將出現,用戶將無法瀏覽到另一個URL。

0
public class ExcelResult : ActionResult 
{ 
    public string FileName { get; set; } 
    public string Path { get;set; } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     context.HttpContext.Response.Buffer = true; 
     context.HttpContext.Response.Clear(); 
     context.HttpContext.Response.AddHeader("content-disposition", "attachment;  filename=" + FileName); 
     context.HttpContext.Response.ContentType = "application/vnd.ms-excel"; 
      context.HttpContext.Response.WriteFile(context.HttpContext.Server.MapPath(Path)); 
    } 
} 

public ExcelResult GetExcelFile() 
{ 
    return new ExcelResult 
       { 
        FileName = "sample.xls", Path = "~/Content/sample.xls" 
       }; 
       }`