通过AJAX MVC下载Excel文件 [英] Download Excel file via AJAX MVC

查看:426
本文介绍了通过AJAX MVC下载Excel文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MVC大(ISH)的形式。

I have a large(ish) form in MVC.

我需要能够产生从这种形式的一个子集包含数据的Excel文件。

I need to be able to generate an excel file containing data from a subset of that form.

棘手的一点是,这不应该影响窗体的其余部分,所以我想通过AJAX来做到这一点。我遇到了似乎与在这么几个问题,但我不能完全制定出什么样的答案的意思。

The tricky bit is that this shouldn't affect the rest of the form and so I want to do it via AJAX. I've come across a few questions on SO that seem to be related, but I can't quite work out what the answers mean.

这一次似乎是最接近我以后是:<一href=\"http://stackoverflow.com/questions/6747532/asp-net-mvc-downloading-excel\">asp-net-mvc-downloading-excel - 但我不知道我理解的反应,现在是一对夫妇岁。我还隔着另一篇文章来了(无法找到它了)关于使用iframe来处理文件下载,但我不知道如何得到这个使用MVC的工作。

This one seems the closest to what I'm after: asp-net-mvc-downloading-excel - but I'm not sure I understand the response, and it is a couple years old now. I also came across another article (can't find it anymore) about using an iframe to handle the file download, but I'm not sure how to get this working with MVC.

我的Excel文件返回的罚款,如果我做一个完整的回发,但我无法得到它的MVC与AJAX的工作。

My excel file returns fine if I'm doing a full post back but I can't get it working with AJAX in mvc.

推荐答案

您不能直接通过AJAX调用因此返回用于下载的文件,另一种方法是使用一个AJAX调用相关数据发布到您的服务器。然后,您可以使用服务器端code创建Excel文件(我会建议使用EPPlus或NPOI这虽然听起来好像你有这部分工作)。一旦该文件已经在服务器上创建为返回值的文件路径(或者只是文件名)回传给你的AJAX调用,然后设置的JavaScript window.location的这个URL,这将促使浏览器下载文件。从最终用户的角度来看,文件下载操作是无缝的,因为他们永远不会离开其上发起请求的页面。

You can't directly return a file for download via an AJAX call so, an alternative approach is to to use an AJAX call to post the related data to your server. You can then use server side code to create the Excel File (I would recommend using EPPlus or NPOI for this although it sounds as if you have this part working). Once the file has been created on the server pass back the path to the file (or just the file-name) as the return value to your AJAX call and then set the JavaScript window.location to this URL which will prompt the browser to download the file. From the end users perspective the file download operation is seamless as they never leave the page on which the request originates.

下面是一个Ajax调用一个简单的人为的例子来实现这一点:

Below is a simple contrived example of an ajax call to achieve this:

$.ajax({
    type: 'POST',
    url: '/Reports/ExportMyData', 
    data: '{ "dataprop1": "test", "dataprop2" : "test2" }',
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    success: function (returnValue) {
        window.location = '/Reports/Download?file=' + returnValue;
    }
});


  • 网址参数是控制器/操作方法,其中的code将创建Excel文件。

  • 数据参数包含将从形式提取的JSON数据。

  • 的returnValue 将新创建的Excel文件的文件名。

  • window.location会命令重定向到实际返回你的文件下载的控制器/操作方法。

    • url parameter is the Controller/Action method where your code will create the Excel file.
    • data parameter contains the json data that would be extracted from the form.
    • returnValue would be the file name of your newly created Excel file.
    • The window.location command redirects to the Controller/Action method that actually returns your file for download.
    • 有关下载操作的示例控制器的方法是:

      A sample controller method for the Download action would be:

      [HttpGet]
      public virtual ActionResult Download(string file)
      {   
        string fullPath = Path.Combine(Server.MapPath("~/MyFiles"), file);
        return File(fullPath, "application/vnd.ms-excel", file);
      }
      

      编辑:

      我原来的答案是3岁以上的,所以我想我会更新,因为我不再在服务器上创建文件下载通过AJAX但是我已经离开了原来的答案文件时,上面可能有一些仍在使用的视您的具体要求。

      My original answer was over 3 years old, so I thought I would update as I no longer create files on the server when downloading files via AJAX however I have left the original answer above as it may be of some use still depending on your specific requirements.

      在我的MVC应用一个常见的​​场景是通过一个网页,有一些用户配置的报告参数(日期范围,过滤器等)的报告。当用户指定他们他们发布到服务器的参数,生成报告(比方说一个Excel文件作为输出),然后我保存生成的文件作为会议的字节数组有一个唯一的参考。此引用传递回为一个JSON结果我的AJAX函数,随后重定向到单独的控制器行动,从会话中提取数据,并下载到最终用户的浏览器。

      A common scenario in my MVC applications is reporting via a web page that has some user configured report parameters (Date Ranges, Filters etc.). When the user has specified the parameters they post them to the server, the report is generated (say for example an Excel file as output) and then I store the resulting file as a byte array in the session with a unique reference. This reference is passed back as a Json Result to my AJAX function that subsequently redirects to separate controller action to extract the data from the Session and download to the end users browser.

      为了让这个更详细,假设你有一个MVC视图绑定了一个模型类形式,让我们称之为模型 ReportVM

      To give this more detail, assuming you have a MVC View that has a form bound to a Model class, lets call the Model ReportVM.

      初​​的控制器操作需要以接收发布模型中,一个例子是:

      First a controller action is required to receive the posted model, an example would be:

      public ActionResult PostReportPartial(ReportVM model){
      
         // Validate the Model is correct and contains valid data
         // Generate your report output based on the model parameters
         // This can be an Excel, PDF, Word file - whatever you need.
      
         // As an example lets assume we've generated an EPPlus ExcelPackage
      
         ExcelPackage workbook = new ExcelPackage();
         // Do something to populate your workbook
      
         // Generate a new unique identifier against which the file can be stored
         string handle = Guid.NewGuid().ToString()
      
         using(MemoryStream memoryStream = new MemoryStream()){
              workbook.SaveAs(memoryStream);
              memoryStream.Position = 0;
              Session[handle] = memoryStream.ToArray();
         }      
      
         // Note we are returning a filename as well as the handle
         return new JsonResult() { 
               Data = new { FileGuid = handle, FileName = "TestReportOutput.xlsx" }
         };
      
      }
      

      Ajax调用的职位我的MVC的形式向上述控制器和接收响应看起来是这样的:

      The AJAX call that posts my MVC form to the above controller and receives the response looks like this:

      $ajax({
          cache: false,
          url: '/Report/PostReportPartial',
          data: _form.serialize(), 
          success: function (data){
               var response = JSON.parse(data);
               window.location = '/Report/Download?fileGuid=' + response.FileGuid 
                                 + '&filename=' + response.FileName;
          }
      })
      

      控制器动作来处理文件的下载:

      The controller action to handle the downloading of the file:

      [HttpGet]
      public virtual ActionResult Download(string fileGuid, string fileName)
      {   
         if(Session[fileGuid] != null){
              byte[] data = Session[fileGuid] as byte[];
              return File(data, "application/vnd.ms-excel", fileName);
         }   
         else{
              // Problem - Log the error, generate a blank file,
              //           redirect to another controller action - whatever fits with your application
              return new EmptyResult();
         }
      }
      

      如果需要的话,可以很容易地被安置的另一个变化是通过文件的MIME类型作为第三个参数,让一个控制器动作可以正确地提供各种输出文件格式。

      One other change that could easily be accommodated if required is to pass the MIME Type of the file as a third parameter, so that the one Controller action could correctly serve a variety of output file formats.

      这将消除任何需要任何物理文件创建并存储在服务器上,所以不需要看家程序,并再次,这是无缝的最终用户。

      This removes any need for any physical files to created and stored on the server, so no housekeeping routines required and once again this is seamless to the end user.

      这篇关于通过AJAX MVC下载Excel文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆