ASP.NET MVC에서 Ajax를 통해 백그라운드 컨트롤러를 호출하면 JSON 개체를 반환할 수 있지만 파일을 직접 반환할 수는 없다는 점을 모두가 알아야 합니다(페이지를 새로 고치지 않으면 Ajax가 아닙니다). 따라서 Ajax를 사용하여 파일을 생성하고 다운로드하려면 먼저 생성된 파일을 서버에 저장한 다음 JSON을 통해 파일 경로를 반환한 다음 다운로드하면 됩니다. 일시적으로 저장되어 있는 경우 해당 파일을 즉시 삭제해야 합니다.
다음은 Excel을 동적으로 생성하는 방법에 대한 예입니다(Excel을 생성하는 특정 단계는 생략했으며 이 기사의 초점은 아닙니다).
1 먼저 작업을 만듭니다. 엑셀 파일 생성
[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 호출 코드를 추가합니다:
//這里我使用了 blockUI 做loading... $.blockUI({ message: '<h3>Please wait a moment...</h3>' }); $.ajax({ type: "POST", url: '@Url.Action("ExportExcel","YourController")', //調用相應的controller/action contentType: "application/json; charset=utf-8", dataType: "json", }).done(function (data) { //console.log(data.result); $.unblockUI(); //接收返回的文件路徑,此文件這時已保存到服務器上了 if (data.fileName != "") { //通過調用 window.location.href 直接跳轉到下載 action 進行文件下載操作 window.location.href = "@Url.RouteUrl(new { Controller = "YourController", Action = "Download"})/?file=" + data.fileName; } });