2011-01-12 2 views
73

J'essaie d'exporter une liste vers un fichier CSV. J'ai tout fait fonctionner jusqu'au point que je veux écrire dans le fichier de réponse. Cela ne fait rien.Exportation au format CSV à l'aide de MVC, C# et jQuery

Voici mon code:

Appelez le la méthode de la page.

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

Le code dans le contrôleur est la suivante:

[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(); 
     } 

Mais après Response.Write(sw) rien ne se passe. Est-il même possible de sauvegarder un fichier de cette façon?

Cordialement

Modifier
Les en-têtes de réponse que je vois quand je clique sur le bouton sont:

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 

qui semble OK pour moi ..

Modifier
I se débarrasser de la partie jQuery en l'a remplacé par un lien hypertexte et cela fonctionne bien pour moi maintenant:

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

Peut-être que cette question sur le SO aide: http: // stackoverflow.com/questions/4522590/unable-to-open-download-save-dialog – Rob

Répondre

207

yan.kun était sur la bonne voie, mais c'est beaucoup plus facile.

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

Comment pourrions-nous gérer les chaînes contenant des virgules? J'ai essayé d'utiliser des guillemets doubles comme qualificatifs de texte, mais cela ne semble pas fonctionner. –

+0

comment faire, nous appelons cette méthode méthode DownloadCSV du script java ?? – mmssaann

+1

@mmssaann C'est la beauté, vous n'utilisez pas javascript. Vous venez de définir le href de votre balise d'ancrage à l'action. 'Download CSV' –

11

Avec MVC vous pouvez simplement retourner un fichier comme celui-ci:

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

Voulez-vous vraiment créer un tas de fichiers sur le serveur Web? Qu'en est-il de les nettoyer? Et la sécurité? – chris

+0

@chris ne crée-t-il pas des fichiers dans la mémoire du serveur plutôt que dans le système de fichiers? – gldraphael

4

Que se passe si vous vous débarrasser de 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

Non, cela ne fait pas de différence non plus. Je l'ai déjà résolu d'une manière différente. Voir ma modification. Merci pour votre aide de toute façon! – Gerard

1

Même si vous avez résolu votre problème, essayez d'exporter csv en utilisant mvc.

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

Respect de Biff, voici quelques tweaks qui me permettent d'utiliser la méthode de rebondir CSV à partir jQuery/Post sur le serveur et revenir comme une invite CSV à l'utilisateur.

[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"); 
    } 

Vous aurez besoin de la ligne de unescape si vous frappez cela d'un formulaire avec le code comme suit,

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

En plus de la réponse de Biff MaGriff. Pour exporter le fichier à l'aide de JQuery, redirigez l'utilisateur vers une nouvelle page.

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

Je pense que vous avez oublié d'utiliser

Response.Flush(); 

sous

Response.Write(sw); 

s'il vous plaît vérifier

-2

fichier Excel simple créer dans mvc 4

résultats de ActionResult publics () { Renvoie le fichier (new System.Text.UTF8Encoding(). GetBytes ("string data"), "application/csv", "filename.csv"); }

+0

Ce n'est pas une bonne réponse. Veuillez vous référer à [Comment écrire une bonne réponse?] (Https://stackoverflow.com/help/how-to-answer) – Clijsters

2

A partir d'un bouton dans la vue, appelez .click (appelez un script java). De là appelez la méthode du contrôleur par window.location.href = 'Controller/Method';

Dans le contrôleur soit faire l'appel de base de données et obtenir le datatable ou appelez une méthode obtenir les données de la table de base de données à un datatable puis faire suivant,

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(); 
          } 
Questions connexes