Ecrire des données dans le fichier CSV en C#

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

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

toute la fonction s'exécute à l'intérieur d'une boucle, et chaque ligne doit être écrite dans le fichier csv . Dans mon cas, la ligne suivante remplace la ligne existante et à la fin je suis seul enregistrement dans le fichier csv qui est la dernière. Comment puis-je écrire toutes les lignes dans le fichier csv .

125
demandé sur Ben 2013-09-12 10:39:11

14 réponses

mise à JOUR

de retour à l'époque naïve, j'ai suggéré de le faire manuellement (c'était une solution simple à une question simple), mais en raison de cela de plus en plus populaire, je recommande d'utiliser la bibliothèque CsvHelper qui fait tous les contrôles de sécurité, etc.

CSV, c'est bien 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 StringBuilder();

//in your loop
    var first = reader[0].ToString();
    var second = image.ToString();
    //Suggestion made by KyleMit
    var newLine = string.Format("{0},{1}", first, second);
    csv.AppendLine(newLine);  

//after your loop
    File.WriteAllText(filePath, csv.ToString());

Ou quelque chose à cet effet. Mon raisonnement est le suivant: vous ne serez pas besoin d'écrire dans le fichier pour chaque élément, vous ne serez en ouvrant le flux une fois et puis l'écriture.

vous pouvez remplacer

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

avec

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

si vous voulez garder les versions précédentes de csv dans le même dossier

C# 6

si vous utilisez c# 6.0 alors vous pouvez faire ce qui suit""

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

MODIFIER

voici un lien à une question qui explique ce que Environment.NewLine fait

207
répondu Johan 2018-01-17 13:34:10

je vous recommande vivement de suivre la voie la plus fastidieuse. Surtout si la taille du fichier.

using(var w = new StreamWriter(path))
{
    for( /* your loop */)
    {
        var first = yourFnToGetFirst();
        var second = yourFnToGetSecond();
        var line = string.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 qui nécessite beaucoup de ressources, plutôt que d'écrire des données dans open stream. Ouvrir\fermer un fichier à l'intérieur d'une boucle entraînera une baisse de performance.

L'approche suggérée par Johan résout ce problème en stockant toute la sortie en mémoire et puis écrire une fois. Cependant (dans le cas de gros fichiers) Votre programme consommera une grande quantité de RAM et même crash avec OutOfMemoryException

un autre avantage de ma solution est que vous pouvez implémenter l'arrêt\resuming en sauvegardant la position actuelle dans les données d'entrée.

upd. Placé en utilisant au bon endroit

66
répondu Pavel Murygin 2014-10-12 22:47:21

écrire des fichiers csv à la main peut être difficile parce que vos données peuvent contenir des virgules et des nouvelles lignes. Je vous suggère d'utiliser une bibliothèque existante à la place.

cette question mentionne quelques options.

y a-t-il des bibliothèques de lecteurs/rédacteurs CSV dans C#?

23
répondu Jeppe Andreasen 2017-05-23 10:31:15

j'utilise une solution à deux parties car c'est très facile à entretenir

// Prepare the values
var allLines = (from trade in proposedTrades
                select new object[] 
                { 
                    trade.TradeType.ToString(), 
                    trade.AccountReference, 
                    trade.SecurityCodeType.ToString(), 
                    trade.SecurityCode, 
                    trade.ClientReference, 
                    trade.TradeCurrency, 
                    trade.AmountDenomination.ToString(), 
                    trade.Amount, 
                    trade.Units, 
                    trade.Percentage, 
                    trade.SettlementCurrency, 
                    trade.FOP, 
                    trade.ClientSettlementAccount, 
                    string.Format("\"{0}\"", trade.Notes),                             
                }).ToList();

// Build the file content
var csv = new StringBuilder();
allLines.ForEach(line => 
{
    csv.AppendLine(string.Join(",", line));            
});

File.WriteAllText(filePath, csv.ToString());
14
répondu user3495843 2014-04-03 23:11:15

utilisez simplement Appendaltext à la place:

File.AppendAllText(filePath, csv);

le seul inconvénient de L'appendice textuel est qu'il va jeter l'erreur quand le fichier n'existe pas, ce qui doit être vérifié

Désolé, blonde moment avant de lire le documentation . Quoi qu'il en soit, la méthode WriteAllText annule tout ce qui a déjà été écrit dans le fichier, si le fichier existe.

notez que votre le code actuel n'utilise pas les nouvelles lignes appropriées, par exemple dans le bloc-notes vous verrez tout cela comme une longue ligne. Changer le code pour avoir de nouvelles lignes appropriées:

string csv = string.Format("{0},{1}{2}", first, image, Environment.NewLine);
9
répondu Shadow Wizard 2013-09-12 06:49:22

au lieu d'appeler chaque fois AppendAllText() vous devriez penser à ouvrir le fichier une fois et puis écrire le contenu entier 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);
    }
}
6
répondu Oliver 2017-11-06 10:21:17
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)
    {
        string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
        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 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.csv");
                        Response.Charset = "";
                        Response.ContentType = "application/text";
                        Response.Output.Write(csv);
                        Response.Flush();
                        Response.End();
                    }
                }
            }
        }
    }
}
5
répondu Alejandro Haro 2016-03-26 04:45:50

au lieu de réinventer la roue, une bibliothèque pourrait être utilisée. CsvHelper est grand pour la création et la lecture de fichiers csv. Ses opérations de lecture et d'écriture sont basées sur des flux et soutiennent donc aussi 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 réflexion, elle prendra n'importe quel type et le analysera directement.

public class CsvRow
{
    public string Column1 { get; set; }
    public bool Column2 { get; set; }

    public CsvRow(string column1, bool column2)
    {
        Column1 = column1;
        Column2 = column2;
    }
}

IEnumerable<CsvRow> 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,véritable

valeur2,false


si vous souhaitez en savoir plus sur les configurations et les possibilités de librarys, vous pouvez le faire ici .

3
répondu NtFreX 2018-07-20 20:23:27

La Manipulation Des Virgules

pour la manipulation des virgules à l'intérieur des valeurs en utilisant string.Format(...) , ce qui suit a fonctionné pour moi:

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

donc pour le combiner avec la réponse de Johan, il ressemblerait à ceci:

//before your loop
var csv = new StringBuilder();

//in your loop
  var first = reader[0].ToString();
  var second = image.ToString();
  //Suggestion made by KyleMit
  var newLine = string.Format("\"{0}\",\"{1}\"", first, second);
  csv.AppendLine(newLine);  

//after your loop
File.WriteAllText(filePath, csv.ToString());

fichier CSV de retour

Si vous voulais simplement retourner le fichier au lieu de l'écrire à un endroit, c'est un exemple de la façon dont j'ai accompli:

D'un procédé stocké

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;

  StringBuilder sbRtn = new StringBuilder();

  // If you want headers for your file
  var header = string.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"].ToString();
      var queryResults = string.Format("\"{0}\",\"{1}\",\"{2}\"",
                                        rdr["Name"].ToString(),
                                        rdr["Address"}.ToString(),
                                        rdr["Phone Number"].ToString()
                                       );
      sbRtn.AppendLine(queryResults);
    }
  }
  thisConnection.Close();

  return File(new System.Text.UTF8Encoding().GetBytes(sbRtn.ToString()), "text/csv", "FileName.csv");
}

D'une liste

/* To help illustrate */
public static List<Person> list = new List<Person>();

/* To help illustrate */
public class Person
{
  public string name;
  public string address;
  public string phoneNumber;
}

/* The important part */
public FileContentResults DownloadCSV()
{
  StringBuilder sbRtn = new StringBuilder();

  // If you want headers for your file
  var header = string.Format("\"{0}\",\"{1}\",\"{2}\"",
                             "Name",
                             "Address",
                             "Phone Number"
                            );
  sbRtn.AppendLine(header);

  foreach (var item in list)
  {
      var listResults = string.Format("\"{0}\",\"{1}\",\"{2}\"",
                                        item.name,
                                        item.address,
                                        item.phoneNumber
                                       );
      sbRtn.AppendLine(listResults);
    }
  }

  return File(new System.Text.UTF8Encoding().GetBytes(sbRtn.ToString()), "text/csv", "FileName.csv");
}

J'espère que c'est utile.

2
répondu Trevor Nestman 2016-10-19 17:52:14

vous pourriez juste avoir à ajouter une ligne d'alimentation "\n\r" .

0
répondu OneWileyDog 2017-09-06 09:13:16

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

List<dynamic> objs = new List<dynamic>();

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'information, veuillez lire l'article CodeProject sur l'utilisation.

0
répondu RajN 2017-10-03 22:04:43

il s'agit d'un simple tutoriel sur la création de fichiers csv en utilisant C# que vous pourrez éditer et développer pour répondre à vos propres besoins.

tout d'abord, vous aurez besoin de créer une nouvelle application Visual Studio C# console, il y a des étapes à suivre pour le faire.

le code d'exemple créera un fichier csv appelé MyTest.csv dans l'emplacement que vous spécifiez. Le contenu du fichier doit être composé de 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.
            string path = @"C:\Users\SomeGuy\Desktop\MyTest.csv";

            // Set the variable "delimiter" to ", ".
            string delimiter = ", ";

            // This text is added only once to the file.
            if (!File.Exists(path))
            {
                // Create a file to write to.
                string 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.
            string 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.
            string readText = File.ReadAllText(path);
            Console.WriteLine(readText);
        }
    }
}
0
répondu Bloggins 2018-04-03 12:55:43

une façon simple de se débarrasser de l'émission d'assurance est d'utiliser File.AppendText pour ajouter la ligne à la fin du fichier comme

void Main()
{
    using (System.IO.StreamWriter sw = System.IO.File.AppendText("file.txt"))
    {          
        string first = reader[0].ToString();
        string second=image.ToString();
        string csv = string.Format("{0},{1}\n", first, second);
        sw.WriteLine(csv);
    }
} 
0
répondu Vinod Srivastav 2018-06-16 14:43:41
 public void UlozCSV()
    {
        using (StreamWriter pisar = new StreamWriter("zbozi.csv", false, Encoding.Default))
        {// u ukládání nezapomenout - za názvem je FALSE
            pisar.WriteLine(hlavicka); //první řešíme hlavičku csv a následně vypisujeme jednotlivé reproduktory

            foreach (Reproduktor item in list)
            {
                pisar.WriteLine(item.ObjektNaCSVRadek()); //metoda která vypíše podle své třídy
            }
        }
    }
0
répondu Hos 2018-09-13 17:26:28