Asp.net MVC使用Ajax实现创建和下载文件教程

标签: Asp.net-MVC ajax
发布时间: 2016/11/29 16:19:36

介绍

当你在Asp.net MVC里使用Ajax调用时, 你只能返回一个JSON对象而不能是文件. 如果你想实现, 你需要在服务器上创建和保存文件,并通过Ajax返回它的路径.

然后你可以调用重定向连接来下载文件,因为它是临时文件,因此你可以在下载完成后删除它.

代码

下面的示例代码将展示如何创建和下载一个Excel文件:

  1. 创建一个生成Excel文件的Action:

    [HttpPost]
    public JsonResult ExportExcel()
    {
        DataTable dt = DataService.GetData();
        var fileName = "Excel_" + DateTime.Now.ToString("yyyyMMddHHmm") + ".xls";
        
        //save the file to server temp folder
        string fullPath = Path.Combine(Server.MapPath("~/temp"), fileName);
    
        using (var exportData = new MemoryStream())
        {
            //I don't show the detail how to create the Excel, this is not the point of this article,
            //I just use the NPOI for Excel handler
            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 the Excel file name
        return Json(new { fileName = fileName, errorMessage = "" });
    }
  2. 创建一个下载Action: 

    [HttpGet]
    [DeleteFileAttribute] //Action Filter, it will auto delete the file after download, 
                          //I will explain it later
    public ActionResult Download(string file)
    {
        //get the temp folder and file path in server
        string fullPath = Path.Combine(Server.MapPath("~/temp"), file);
    
        //return the file for download, this is an Excel 
        //so I set the file content type to "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();
    
            //convert the current filter context to file and get the file path
            string filePath = (filterContext.Result as FilePathResult).FileName;
            
            //delete the file after download
            System.IO.File.Delete(filePath);
        }
    }
  4. 在前台使用Ajax调用:

    //I use blockUI for loading...
    $.blockUI({ message: '<h3>Please wait a moment...</h3>' });    
    $.ajax({
        type: "POST",
        url: '@Url.Action("ExportExcel","YourController")', //call your controller and action
        contentType: "application/json; charset=utf-8",
        dataType: "json",
    }).done(function (data) {
        //console.log(data.result);
        $.unblockUI();
    
        //get the file name for download
        if (data.fileName != "") {
            //use window.location.href for redirect to download action for download the file
            window.location.href = "@Url.RouteUrl(new 
                { Controller = "YourController", Action = "Download"})/?file=" + data.fileName;
        }
    });
官方微信
官方QQ群
31647020