Écrire des données dans un fichier CSV en C #

J’essaie d’écrire dans un fichier csv ligne par ligne en utilisant le langage C #. Voici ma fonction

 ssortingng first = reader[0].ToSsortingng(); ssortingng second=image.ToSsortingng(); ssortingng csv = ssortingng.Format("{0},{1}\n", first, second); File.WriteAllText(filePath, csv); 

Toute la fonction s’exécute dans une boucle et chaque ligne doit être écrite dans le fichier csv . Dans mon cas, la ligne suivante écrase la ligne existante et à la fin, je ne reçois qu’un seul enregistrement dans le fichier csv qui est le dernier. Comment puis-je écrire toutes les lignes dans le fichier csv .

METTRE À JOUR

Dans mes jours de naïf, j’ai suggéré de le faire manuellement (c’était une solution simple à une simple question), mais étant donné que cela devenait de plus en plus populaire, je recommande d’utiliser la bibliothèque CsvHelper qui effectue tous les contrôles de sécurité, etc.

Le CSV est beaucoup plus compliqué que ce que la question / réponse suggère.

Réponse originale

Comme vous avez déjà une boucle, envisagez de le faire comme ceci:

 //before your loop var csv = new SsortingngBuilder(); //in your loop var first = reader[0].ToSsortingng(); var second = image.ToSsortingng(); //Suggestion made by KyleMit var newLine = ssortingng.Format("{0},{1}", first, second); csv.AppendLine(newLine); //after your loop File.WriteAllText(filePath, csv.ToSsortingng()); 

Ou quelque chose à cet effet. Mon raisonnement est le suivant: vous n’aurez pas besoin d’écrire dans le fichier pour chaque élément, vous n’ouvrirez le stream qu’une seule fois, puis vous y écrirez.

Vous pouvez remplacer

 File.WriteAllText(filePath, csv.ToSsortingng()); 

avec

 File.AppendAllText(filePath, csv.ToSsortingng()); 

si vous souhaitez conserver les versions précédentes de csv dans le même fichier

C # 6

Si vous utilisez c # 6.0, vous pouvez faire ce qui suit

 var newLine = $"{first},{second}" 

MODIFIER

Voici un lien vers une question qui explique ce que fait Environment.NewLine

Je vous recommande fortement d’aller sur la route la plus fastidieuse. Surtout si la taille de votre fichier est importante.

 using(var w = new StreamWriter(path)) { for( /* your loop */) { var first = yourFnToGetFirst(); var second = yourFnToGetSecond(); var line = ssortingng.Format("{0},{1}", first, second); w.WriteLine(line); w.Flush(); } } 

File.AppendAllText() ouvre un nouveau fichier, écrit le contenu, puis ferme le fichier. L’ouverture de fichiers est une opération très gourmande en ressources que l’écriture de données dans un stream ouvert. Ouvrir \ fermer un fichier dans une boucle entraînera une baisse des performances.

L’approche proposée par Johan résout ce problème en stockant toutes les sorties en mémoire et en les écrivant une fois. Cependant (dans le cas de gros fichiers), vous programmez une grande quantité de mémoire vive et même tomber en panne avec OutOfMemoryException

Un autre avantage de ma solution est que vous pouvez mettre en œuvre une pause \ reprise en sauvegardant la position actuelle dans les données d’entrée.

mise à jour Placé en utilisant au bon endroit

Écrire des fichiers csv à la main peut être difficile car vos données peuvent contenir des virgules et des nouvelles lignes. Je vous suggère d’utiliser plutôt une bibliothèque existante.

Cette question mentionne quelques options.

Existe-t-il des bibliothèques de lecteurs / graveurs CSV en C #?

J’utilise une solution à deux pares car il est très facile de maintenir

 // Prepare the values var allLines = (from trade in proposedTrades select new object[] { trade.TradeType.ToSsortingng(), trade.AccountReference, trade.SecurityCodeType.ToSsortingng(), trade.SecurityCode, trade.ClientReference, trade.TradeCurrency, trade.AmountDenomination.ToSsortingng(), trade.Amount, trade.Units, trade.Percentage, trade.SettlementCurrency, trade.FOP, trade.ClientSettlementAccount, ssortingng.Format("\"{0}\"", trade.Notes), }).ToList(); // Build the file content var csv = new SsortingngBuilder(); allLines.ForEach(line => { csv.AppendLine(ssortingng.Join(",", line)); }); File.WriteAllText(filePath, csv.ToSsortingng()); 

Utilisez simplement AppendAllText à la place:

 File.AppendAllText(filePath, csv); 

Le seul inconvénient de AppendAllText est qu’il jettera une erreur lorsque le fichier n’existe pas, il faut donc vérifier

Désolé, moment blond avant de lire la documentation . Quoi qu’il en soit, la méthode WriteAllText remplace tout ce qui était précédemment écrit dans le fichier, si le fichier existe.

Notez que votre code actuel n’utilise pas les nouvelles lignes appropriées, par exemple dans le Bloc-notes, vous verrez tout comme une longue ligne. Modifiez le code à ceci pour avoir de nouvelles lignes appropriées:

 ssortingng csv = ssortingng.Format("{0},{1}{2}", first, image, Environment.NewLine); 

Au lieu d’appeler à chaque fois AppendAllText() vous devriez penser à ouvrir le fichier une fois, puis à écrire tout le contenu une fois:

 var file = @"C:\myOutput.csv"; using (var stream = File.CreateText(file)) { for (int i = 0; i < reader.Count(); i++) { string first = reader[i].ToString(); string second = image.ToString(); string csvRow = string.Format("{0},{1}", first, second); stream.WriteLine(csvRow); } } 
 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data; using System.Configuration; using System.Data.SqlClient; public partial class CS : System.Web.UI.Page { protected void ExportCSV(object sender, EventArgs e) { ssortingng constr = ConfigurationManager.ConnectionSsortingngs["constr"].ConnectionSsortingng; using (SqlConnection con = new SqlConnection(constr)) { using (SqlCommand cmd = new SqlCommand("SELECT * FROM Customers")) { using (SqlDataAdapter sda = new SqlDataAdapter()) { cmd.Connection = con; sda.SelectCommand = cmd; using (DataTable dt = new DataTable()) { sda.Fill(dt); //Build the CSV file data as a Comma separated ssortingng. ssortingng csv = ssortingng.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].ToSsortingng().Replace(",", ";") + ','; } //Add new line. csv += "\r\n"; } //Download the CSV file. Response.Clear(); Response.Buffer = true; Response.AddHeader("content-disposition", "attachment;filename=SqlExport.csv"); Response.Charset = ""; Response.ContentType = "application/text"; Response.Output.Write(csv); Response.Flush(); Response.End(); } } } } } } 

Manipulation des virgules

Pour gérer les virgules à l’intérieur des valeurs lors de l’utilisation de ssortingng.Format(...) , ce qui suit a fonctionné pour moi:

 var newLine = ssortingng.Format("\"{0}\",\"{1}\",\"{2}\"", first, second, third ); csv.AppendLine(newLine); 

Donc, pour le combiner avec la réponse de Johan, cela ressemblerait à ceci:

 //before your loop var csv = new SsortingngBuilder(); //in your loop var first = reader[0].ToSsortingng(); var second = image.ToSsortingng(); //Suggestion made by KyleMit var newLine = ssortingng.Format("\"{0}\",\"{1}\"", first, second); csv.AppendLine(newLine); //after your loop File.WriteAllText(filePath, csv.ToSsortingng()); 

Renvoyer un fichier CSV

Si vous vouliez simplement retourner le fichier au lieu de l’écrire dans un emplacement, voici un exemple de ce que j’ai accompli:

A partir d’une procédure stockée

 public FileContentResults DownloadCSV() { // I have a stored procedure that queries the information I need SqlConnection thisConnection = new SqlConnection("Data Source=sv12sql;User ID=UI_Readonly;Password=SuperSecure;Initial Catalog=DB_Name;Integrated Security=false"); SqlCommand queryCommand = new SqlCommand("spc_GetInfoINeed", thisConnection); queryCommand.CommandType = CommandType.StoredProcedure; SsortingngBuilder sbRtn = new SsortingngBuilder(); // If you want headers for your file var header = ssortingng.Format("\"{0}\",\"{1}\",\"{2}\"", "Name", "Address", "Phone Number" ); sbRtn.AppendLine(header); // Open Database Connection thisConnection.Open(); using (SqlDataReader rdr = queryCommand.ExecuteReader()) { while (rdr.Read()) { // rdr["COLUMN NAME"].ToSsortingng(); var queryResults = ssortingng.Format("\"{0}\",\"{1}\",\"{2}\"", rdr["Name"].ToSsortingng(), rdr["Address"}.ToSsortingng(), rdr["Phone Number"].ToSsortingng() ); sbRtn.AppendLine(queryResults); } } thisConnection.Close(); return File(new System.Text.UTF8Encoding().GetBytes(sbRtn.ToSsortingng()), "text/csv", "FileName.csv"); } 

À partir d’une liste

 /* To help illustrate */ public static List list = new List(); /* To help illustrate */ public class Person { public ssortingng name; public ssortingng address; public ssortingng phoneNumber; } /* The important part */ public FileContentResults DownloadCSV() { SsortingngBuilder sbRtn = new SsortingngBuilder(); // If you want headers for your file var header = ssortingng.Format("\"{0}\",\"{1}\",\"{2}\"", "Name", "Address", "Phone Number" ); sbRtn.AppendLine(header); foreach (var item in list) { var listResults = ssortingng.Format("\"{0}\",\"{1}\",\"{2}\"", item.name, item.address, item.phoneNumber ); sbRtn.AppendLine(listResults); } } return File(new System.Text.UTF8Encoding().GetBytes(sbRtn.ToSsortingng()), "text/csv", "FileName.csv"); } 

J’espère que cela est utile.

Au lieu de réinventer la roue, une bibliothèque pourrait être utilisée. CsvHelper est idéal pour créer et lire des fichiers csv. Ses opérations de lecture et d’écriture sont basées sur les stream et prennent donc également en charge les opérations avec une grande quantité de données.


Vous pouvez écrire votre csv comme suit.

 using(var textWriter = new StreamWriter(@"C:\mypath\myfile.csv")) { var writer = new CsvWriter(textWriter); writer.Configuration.Delimiter = ","; foreach (var item in list) { writer.WriteField( "a" ); writer.WriteField( 2 ); writer.WriteField( true ); writer.NextRecord(); } } 

Comme la bibliothèque utilise la reflection, elle prendra n’importe quel type et l’parsingra directement.

 public class CsvRow { public ssortingng Column1 { get; set; } public bool Column2 { get; set; } public CsvRow(ssortingng column1, bool column2) { Column1 = column1; Column2 = column2; } } IEnumerable rows = new [] { new CsvRow("value1", true), new CsvRow("value2", false) }; using(var textWriter = new StreamWriter(@"C:\mypath\myfile.csv") { var writer = new CsvWriter(textWriter); writer.Configuration.Delimiter = ","; writer.WriteRecords(rows); } 

valeur1, vrai

value2, false


Si vous voulez en savoir plus sur les configurations et les possibilités de la bibliothèque, vous pouvez le faire ici .

Vous devrez peut-être simplement append un saut de ligne "\n\r" .

Voici une autre bibliothèque open source pour créer facilement un fichier CSV, Cinchoo ETL

 List objs = new List(); dynamic rec1 = new ExpandoObject(); rec1.Id = 10; rec1.Name = @"Mark"; rec1.JoinedDate = new DateTime(2001, 2, 2); rec1.IsActive = true; rec1.Salary = new ChoCurrency(100000); objs.Add(rec1); dynamic rec2 = new ExpandoObject(); rec2.Id = 200; rec2.Name = "Tom"; rec2.JoinedDate = new DateTime(1990, 10, 23); rec2.IsActive = false; rec2.Salary = new ChoCurrency(150000); objs.Add(rec2); using (var parser = new ChoCSVWriter("emp.csv").WithFirstLineHeader()) { parser.Write(objs); } 

Pour plus d’informations, veuillez lire l’article CodeProject sur l’utilisation.

Ceci est un tutoriel simple sur la création de fichiers CSV en C # que vous pourrez modifier et développer pour répondre à vos besoins.

Vous devez d’abord créer une nouvelle application console Visual Studio C #, il y a des étapes à suivre pour ce faire.

L’exemple de code créera un fichier csv appelé MyTest.csv à l’emplacement que vous spécifiez. Le contenu du fichier doit comporter 3 colonnes nommées avec du texte dans les 3 premières lignes.

https://tidbytez.com/2018/02/06/how-to-create-a-csv-file-with-c/

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace CreateCsv { class Program { static void Main() { // Set the path and filename variable "path", filename being MyTest.csv in this example. // Change SomeGuy for your username. ssortingng path = @"C:\Users\SomeGuy\Desktop\MyTest.csv"; // Set the variable "delimiter" to ", ". ssortingng delimiter = ", "; // This text is added only once to the file. if (!File.Exists(path)) { // Create a file to write to. ssortingng createText = "Column 1 Name" + delimiter + "Column 2 Name" + delimiter + "Column 3 Name" + delimiter + Environment.NewLine; File.WriteAllText(path, createText); } // This text is always added, making the file longer over time // if it is not deleted. ssortingng appendText = "This is text for Column 1" + delimiter + "This is text for Column 2" + delimiter + "This is text for Column 3" + delimiter + Environment.NewLine; File.AppendAllText(path, appendText); // Open the file to read from. ssortingng readText = File.ReadAllText(path); Console.WriteLine(readText); } } } 

Un moyen simple de se débarrasser du problème de réécriture consiste à utiliser File.AppendText pour append une ligne à la fin du fichier en tant que

 void Main() { using (System.IO.StreamWriter sw = System.IO.File.AppendText("file.txt")) { ssortingng first = reader[0].ToSsortingng(); ssortingng second=image.ToSsortingng(); ssortingng csv = ssortingng.Format("{0},{1}\n", first, second); sw.WriteLine(csv); } }