ASP.NET MVC では、Ajax 経由でバックグラウンド コントローラーを呼び出した場合、JSON オブジェクトを返すことはできますが、ファイルを直接返すことはできません (ページを更新しない限り、それは Ajax ではありません)。 Ajax がファイルを生成してダウンロードする場合は、生成されたファイルを最初にサーバーに保存し、ダウンロードする前にファイルのパスを JSON で返すだけで済みます。 もちろん、一時的に保存されるため、ダウンロードする必要があります。対応するドキュメントはダウンロード後すぐに削除されます。
以下は Excel を動的に生成する方法の例です (Excel を生成する具体的な手順は省略しました。これはこの記事の焦点ではありません):
1. まず Excel ファイルを生成するアクションを作成します
[HttpPost] public JsonResult ExportExcel() { DataTable dt = DataService.GetData(); var fileName = "Excel_" + DateTime.Now.ToString("yyyyMMddHHmm") + ".xls"; //將生成的文件保存到服務器的臨時目錄里 string fullPath = Path.Combine(Server.MapPath("~/temp"), fileName); using (var exportData = new MemoryStream()) { //如何生成Excel這里就不詳細說明啦,我這里對Excel的操作使用的是 NPOI Utility.WriteDataTableToExcel(dt, ".xls", exportData); FileStream file = new FileStream(fullPath, FileMode.Create, FileAccess.Write); exportData.WriteTo(file); file.Close(); } var errorMessage = "you can return the errors in here!"; //返回生成的文件名 return Json(new { fileName = fileName, errorMessage = "" }); }
2. ダウンロード アプリケーションのアクションを作成します
[HttpGet] [DeleteFileAttribute] //Action Filter, 下載完后自動刪除文件,這個屬性稍後解釋 public ActionResult Download(string file) { //到服務器臨時文件目錄下載相應的文件 string fullPath = Path.Combine(Server.MapPath("~/temp"), file); //返回文件對象,這里用的是Excel,所以文件頭使用了 "application/vnd.ms-excel" return File(fullPath, "application/vnd.ms-excel", file); }
3. ダウンロード後にファイルを自動的に削除するため、別のアクション フィルターを作成します
public class DeleteFileAttribute : ActionFilterAttribute { public override void OnResultExecuted(ResultExecutedContext filterContext) { filterContext.HttpContext.Response.Flush(); //將當前filter context轉換成具體操作的文件并獲取文件路徑 string filePath = (filterContext.Result as FilePathResult).FileName; //有文件路徑后就可以直接刪除相關文件了 System.IO.File.Delete(filePath); } }
4. 最後に、Ajax 呼び出しコードをフォアグラウンドに追加します。