2011-01-12 76 views
73

我试图将列表导出为CSV文件。 我已经完成了所有工作,直到我想写入文件到响应流为止。这没有做任何事情。使用MVC,C#和jQuery导出为CSV

这是我的代码:

从页面调用该方法。

$('#btn_export').click(function() { 
     $.post('NewsLetter/Export'); 
}); 

控制器中的代码如下:

[HttpPost] 
     public void Export() 
     { 
      try 
      { 
       var filter = Session[FilterSessionKey] != null ? Session[FilterSessionKey] as SubscriberFilter : new SubscriberFilter(); 

       var predicate = _subscriberService.BuildPredicate(filter); 
       var compiledPredicate = predicate.Compile(); 
       var filterRecords = _subscriberService.GetSubscribersInGroup().Where(x => !x.IsDeleted).AsEnumerable().Where(compiledPredicate).GroupBy(s => s.Subscriber.EmailAddress).OrderBy(x => x.Key); 

       ExportAsCSV(filterRecords); 
      } 
      catch (Exception exception) 
      { 
       Logger.WriteLog(LogLevel.Error, exception); 
      } 
     } 

     private void ExportAsCSV(IEnumerable<IGrouping<String, SubscriberInGroup>> filterRecords) 
     { 
      var sw = new StringWriter(); 
      //write the header 
      sw.WriteLine(String.Format("{0},{1},{2},{3}", CMSMessages.EmailAddress, CMSMessages.Gender, CMSMessages.FirstName, CMSMessages.LastName)); 

      //write every subscriber to the file 
      var resourceManager = new ResourceManager(typeof(CMSMessages)); 
      foreach (var record in filterRecords.Select(x => x.First().Subscriber)) 
      { 
       sw.WriteLine(String.Format("{0},{1},{2},{3}", record.EmailAddress, record.Gender.HasValue ? resourceManager.GetString(record.Gender.ToString()) : "", record.FirstName, record.LastName)); 
      } 

      Response.Clear(); 
      Response.AddHeader("Content-Disposition", "attachment; filename=adressenbestand.csv"); 
      Response.ContentType = "text/csv"; 
      Response.Write(sw); 
      Response.End(); 
     } 

但经过Response.Write(sw)什么也没有发生。这种方式甚至可以保存文件吗?

问候

编辑
的响应头我看到当我点击按钮,分别是:

HTTP/1.1 200 OK 
Cache-Control: private 
Content-Type: text/csv; charset=utf-8 
Server: Microsoft-IIS/7.5 
X-AspNetMvc-Version: 2.0 
Content-Disposition: attachment; filename=adressenbestand.csv 
X-Powered-By: ASP.NET 
Date: Wed, 12 Jan 2011 13:05:42 GMT 
Content-Length: 113 

这似乎确定我..

编辑
我摆脱了jQuery的部分取而代之的超链接,这是行得通对我很好,现在:

<a class="export" href="NewsLetter/Export">exporteren</a> 
+1

也许在SO这个问题可以帮助:HTTP:// stackoverflow.com/questions/4522590/unable-to-open-download-save-dialog – Rob 2011-01-12 13:29:10

回答

207

yan.kun是在正确的轨道上,但这要容易得多。

public FileContentResult DownloadCSV() 
    { 
     string csv = "Charlie, Chaplin, Chuckles"; 
     return File(new System.Text.UTF8Encoding().GetBytes(csv), "text/csv", "Report123.csv"); 
    } 
+0

我们将如何处理包含逗号的字符串?我尝试使用双引号作为文本限定符,但它似乎不工作。 – 2013-03-30 03:03:46

11

在MVC中,你可以简单地返回一个像这样的文件:

public ActionResult ExportData() 
{ 
    System.IO.FileInfo exportFile = //create your ExportFile 
    return File(exportFile.FullName, "text/csv", string.Format("Export-{0}.csv", DateTime.Now.ToString("yyyyMMdd-HHmmss"))); 
} 
+8

你真的想在Web服务器上创建一堆文件吗?怎么样清理它们?安全性如何? – chris 2011-01-12 13:29:24

+0

@chris不会在服务器的内存中创建文件而不是在文件系统中创建文件? – gldraphael 2015-06-13 19:55:07

4

,如果你摆脱StringWriter的,会发生什么:

 Response.Clear(); 
     Response.AddHeader("Content-Disposition", "attachment; filename=adressenbestand.csv"); 
     Response.ContentType = "text/csv"; 
     //write the header 
     Response.Write(String.Format("{0},{1},{2},{3}", CMSMessages.EmailAddress, CMSMessages.Gender, CMSMessages.FirstName, CMSMessages.LastName)); 

     //write every subscriber to the file 
     var resourceManager = new ResourceManager(typeof(CMSMessages)); 
     foreach (var record in filterRecords.Select(x => x.First().Subscriber)) 
     { 
      Response.Write(String.Format("{0},{1},{2},{3}", record.EmailAddress, record.Gender.HasValue ? resourceManager.GetString(record.Gender.ToString()) : "", record.FirstName, record.LastName)); 
     } 

     Response.End(); 
+0

nope也没有区别。我以不同的方式解决了所有问题。看我的编辑。还是要谢谢你的帮助! – Gerard 2011-01-12 13:36:00

1

即使你已经解决了你的问题,这里是另一个尝试使用mvc导出csv。

return new FileStreamResult(fileStream, "text/csv") { FileDownloadName = fileDownloadName }; 
3

对于比夫,这里有一些调整,让我使用的方法从jQuery的/立柱弹回CSV针对服务器,回来为CSV提示给用户。

[Themed(false)] 
    public FileContentResult DownloadCSV() 
    { 

     var csvStringData = new StreamReader(Request.InputStream).ReadToEnd(); 

     csvStringData = Uri.UnescapeDataString(csvStringData.Replace("mydata=", "")); 

     return File(new System.Text.UTF8Encoding().GetBytes(csvStringData), "text/csv", "report.csv"); 
    } 

你需要的UNESCAPE行,如果你打这个从形式类似下面的代码,

var input = $("<input>").attr("type", "hidden").attr("name", "mydata").val(data); 
    $('#downloadForm').append($(input)); 
    $("#downloadForm").submit(); 
6

除了比夫MaGriff的答案。要使用JQuery导出文件,请将用户重定向到新页面。

$('#btn_export').click(function() { 
    window.location.href = 'NewsLetter/Export'; 
}); 
0

我想你已经忘记用

Response.Flush(); 

Response.Write(sw); 

下请

-2

简单的Excel文件中的MVC创建4个

公众的ActionResult结果( ) return File(new System.Text.UTF8Encoding()。GetBytes(“string data”),“application/csv”,“filename.csv”); }

2

从视图中的按钮调用.click(调用一些Java脚本)。从那里通过window.location.href ='Controller/Method'调用控制器方法;

在控制器要么做数据库调用并获得数据表或调用一些方法从数据库表中的数据得到一个数据表,然后做下面,

using (DataTable dt = new DataTable()) 
         { 
          sda.Fill(dt); 
          //Build the CSV file data as a Comma separated string. 
          string csv = string.Empty; 
          foreach (DataColumn column in dt.Columns) 
          { 
           //Add the Header row for CSV file. 
           csv += column.ColumnName + ','; 
          } 
          //Add new line. 
          csv += "\r\n"; 
          foreach (DataRow row in dt.Rows) 
          { 
           foreach (DataColumn column in dt.Columns) 
           { 
            //Add the Data rows. 
            csv += row[column.ColumnName].ToString().Replace(",", ";") + ','; 
           } 
           //Add new line. 
           csv += "\r\n"; 
          } 
          //Download the CSV file. 
          Response.Clear(); 
          Response.Buffer = true; 
          Response.AddHeader("content-disposition", "attachment;filename=SqlExport"+DateTime.Now+".csv"); 
          Response.Charset = ""; 
          //Response.ContentType = "application/text"; 
          Response.ContentType = "application/x-msexcel"; 
          Response.Output.Write(csv); 
          Response.Flush(); 
          Response.End(); 
          }