it-swarm.com.de

Daten in CSV-Datei in C # schreiben

Ich versuche, Zeile für Zeile in eine csv-Datei mit C # -Sprache zu schreiben. Hier ist meine Funktion

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

Die gesamte Funktion wird in einer Schleife ausgeführt und jede Zeile sollte in die csv-Datei geschrieben werden. In meinem Fall überschreibt die nächste Zeile die vorhandene Zeile und am Ende bekomme ich nur einen einzigen Datensatz in der CSV-Datei, der letzte. Wie schreibe ich alle Zeilen in die csv-Datei? 

138
rampuriyaaa

UPDATE

In meinen naiven Tagen schlug ich vor, dies manuell zu tun (es war eine einfache Lösung für eine einfache Frage), aber da dies immer beliebter wird, würde ich empfehlen, die Bibliothek CsvHelper zu verwenden, die alles tut die Sicherheitskontrollen usw. 

CSV ist viel komplizierter als das, was die Frage/Antwort nahelegt.

Originalantwort

Da Sie bereits über eine Schleife verfügen, sollten Sie dies folgendermaßen tun:

//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());

Oder etwas zu diesem Effekt ... Meine Begründung ist: Sie müssen nicht für jedes Element in die Datei schreiben, Sie werden den Stream nur einmal öffnen und dann schreiben.

Sie können ersetzen

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

mit 

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

wenn Sie frühere Versionen von csv in derselben Datei behalten möchten

C # 6

Wenn Sie c # 6.0 verwenden, können Sie Folgendes tun

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

EDIT

Hier ist ein Link zu einer Frage, die erklärt, was Environment.NewLine tut

236
Johan

Ich würde Ihnen wärmstens empfehlen, den etwas langwierigsten Weg zu gehen. Besonders wenn Ihre Dateigröße groß ist.

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() öffnet eine neue Datei, schreibt den Inhalt und schließt die Datei. Das Öffnen von Dateien ist ein sehr ressourcenintensiver Vorgang als das Schreiben von Daten in den offenen Stream. Das Öffnen\Schließen einer Datei innerhalb einer Schleife führt zu Leistungseinbußen. 

Der von Johan vorgeschlagene Ansatz löst dieses Problem, indem die gesamte Ausgabe im Speicher abgelegt und dann einmal geschrieben wird. (Bei großen Dateien) verbraucht Ihr Programm jedoch viel RAM und stürzt sogar mit OutOfMemoryException ab.

Ein weiterer Vorteil meiner Lösung ist, dass Sie das Anhalten/Wiederaufnehmen implementieren können, indem Sie die aktuelle Position in den Eingabedaten speichern.

upd. Platziert an der richtigen Stelle

71
Pavel Murygin

Das manuelle Schreiben von CSV-Dateien kann schwierig sein, da Ihre Daten Kommas und Zeilenumbrüche enthalten können. Ich schlage vor, dass Sie stattdessen eine vorhandene Bibliothek verwenden. 

Diese Frage nennt einige Möglichkeiten.

Gibt es in C # CSV-Reader/Writer-Bibliotheken?

24
Jeppe Andreasen

Ich verwende eine Zwei-Analyse-Lösung, da sie sehr einfach zu warten ist

// 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
user3495843

Verwenden Sie stattdessen einfach AppendAllText:

File.AppendAllText(filePath, csv);

Der einzige Nachteil von AppendAllText besteht darin, dass ein Fehler ausgegeben wird, wenn die Datei nicht vorhanden ist. Daher muss dies geprüft werden

Sorry, blonder Moment, bevor Sie die Dokumentation lesen. In jedem Fall überschreibt die WriteAllText-Methode alles, was zuvor in die Datei geschrieben wurde, sofern die Datei vorhanden ist.

Beachten Sie, dass Ihr aktueller Code keine richtigen neuen Zeilen verwendet. In Notepad sehen Sie beispielsweise alles als eine lange Zeile. Ändern Sie den Code in dieses, um richtige neue Zeilen zu erhalten:

string csv = string.Format("{0},{1}{2}", first, image, Environment.NewLine);
9
Shadow Wizard

Anstatt jedes Mal AppendAllText() aufzurufen, sollten Sie die Datei einmal öffnen und dann den gesamten Inhalt einmal schreiben:

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
Oliver
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();
                    }
                }
            }
        }
    }
}
4
Alejandro Haro

Anstatt das Rad neu zu erfinden, könnte eine Bibliothek verwendet werden. CsvHelper eignet sich hervorragend zum Erstellen und Lesen von CSV-Dateien. Die Lese- und Schreiboperationen basieren auf Streams und unterstützen daher auch Operationen mit einer großen Datenmenge.


Sie können Ihre CSV wie folgt schreiben.

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

Da die Bibliothek die Reflektion verwendet, nimmt sie jeden Typ und analysiert sie direkt.

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

wert1, wahr

value2, false


Wenn Sie mehr über die Konfigurationen und Möglichkeiten der Bibliotheken erfahren möchten, können Sie dies tun hier .

4
NtFreX

Umgang mit Kommas

Beim Umgang mit Kommas innerhalb von Werten bei Verwendung von string.Format(...) hat sich Folgendes für mich bewährt:

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

Um es mit Johans Antwort zu kombinieren, würde es so aussehen:

//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());

CSV-Datei zurückgeben

Wenn Sie die Datei einfach zurückgeben möchten, anstatt sie an einen Speicherort zu schreiben, ist dies ein Beispiel, wie ich sie erreicht habe:

Aus einem gespeicherten Verfahren

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

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

Hoffentlich ist das hilfreich.

2
Trevor Nestman

Hier ist eine weitere Open Source-Bibliothek zum einfachen Erstellen von CSV-Dateien. 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);
}

Weitere Informationen finden Sie im Artikel CodeProject zur Verwendung.

0
RajN

Dies ist ein einfaches Tutorial zum Erstellen von CSV-Dateien mit C #, das Sie bearbeiten und erweitern können, um es an Ihre eigenen Bedürfnisse anzupassen.

Zunächst müssen Sie eine neue Visual Studio C # -Konsolenanwendung erstellen. Dazu müssen Sie folgende Schritte ausführen.

Der Beispielcode erstellt eine CSV-Datei mit dem Namen MyTest.csv am angegebenen Speicherort. Der Inhalt der Datei sollte 3 benannte Spalten mit Text in den ersten 3 Zeilen sein.

https://tidbytez.com/2018/02/06/wie-zu-erstellen-a-csv-datei-mit-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
Bloggins

Sie müssen möglicherweise nur einen Zeilenvorschub "\n\r" hinzufügen.

0
OneWileyDog
 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
Hos

Eine einfache Möglichkeit, das Überschreibungsproblem zu beseitigen, besteht darin, mit File.AppendText eine Zeile am Ende der Datei als anzufügen 

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
Vinod Srivastav