Ik probeer rij voor rij in een csv
-bestand te schrijven met behulp van de taal C#. Hier is mijn functie
string first = reader[0].ToString();
string second=image.ToString();
string csv = string.Format("{0},{1}\n", first, second);
File.WriteAllText(filePath, csv);
De hele functie draait in een lus en elke rij moet naar het bestand csv
worden geschreven. In mijn geval overschrijft de volgende rij de bestaande rij en uiteindelijk krijg ik maar één record in het csv-bestand dat het laatste is. Hoe kan ik alle rijen in het csv
-bestand schrijven?
Antwoord 1, autoriteit 100%
UPDATE
In mijn naïeve dagen stelde ik voor dit handmatig te doen (het was een eenvoudige oplossing voor een simpele vraag), maar omdat dit steeds populairder wordt, raad ik aan om de bibliotheek CsvHelperdie alle veiligheidscontroles uitvoert, enz.
CSV is veel ingewikkelder dan wat de vraag/het antwoord suggereert.
Oorspronkelijk antwoord
Aangezien je al een lus hebt, overweeg dan om het als volgt te doen:
//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());
Of iets in die richting.
Mijn redenering is: je hoeft niet voor elk item naar het bestand te schrijven, je opent de stream maar één keer en schrijft er vervolgens naar.
U kunt vervangen
File.WriteAllText(filePath, csv.ToString());
met
File.AppendAllText(filePath, csv.ToString());
als u eerdere versies van csv in hetzelfde bestand wilt bewaren
C# 6
Als u c# 6.0 gebruikt, kunt u het volgende doen
var newLine = $"{first},{second}"
BEWERKEN
Hier is een linknaar een vraag die uitlegt wat Environment.NewLine
wel.
Antwoord 2, autoriteit 29%
Ik zou je ten zeerste aanbevelen om de meer saaie route te nemen. Vooral als je bestandsgrootte groot is.
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()
opent een nieuw bestand, schrijft de inhoud en sluit het bestand. Het openen van bestanden is een veel arbeidsintensievere operatie dan het schrijven van gegevens in open stream. Het openen/sluiten van een bestand in een lus leidt tot prestatieverlies.
De door Johan voorgestelde aanpak lost dat probleem op door alle uitvoer in het geheugen op te slaan en deze vervolgens eenmaal te schrijven. Echter (in het geval van grote bestanden) zal uw programma een grote hoeveelheid RAM verbruiken en zelfs crashen met OutOfMemoryException
Een ander voordeel van mijn oplossing is dat u pauzeren/hervatten kunt implementeren door de huidige positie op te slaan in invoergegevens.
op. Geplaatst met op de juiste plaats
Antwoord 3, autoriteit 10%
Het handmatig schrijven van csv-bestanden kan moeilijk zijn omdat uw gegevens komma’s en nieuwe regels kunnen bevatten. Ik raad u aan in plaats daarvan een bestaande bibliotheek te gebruiken.
Deze vraag noemt een paar opties.
Zijn er CSV-lezers/schrijversbibliotheken in C#?
Antwoord 4, autoriteit 5%
Ik gebruik een oplossing met twee ontledingen omdat het heel gemakkelijk te onderhouden is
// 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());
Antwoord 5, autoriteit 4%
In plaats van elke keer AppendAllText()
aan te roepen, zou je kunnen overwegen om het bestand één keer te openen en dan de hele inhoud één keer te schrijven:
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);
}
}
Antwoord 6, autoriteit 4%
U kunt in plaats daarvan AppendAllText
gebruiken:
File.AppendAllText(filePath, csv);
Als de documentatie van WriteAllText
zegt:
Als het doelbestand al bestaat, wordt het overschreven
Houd er ook rekening mee dat uw huidige code niet de juiste nieuwe regels gebruikt, bijvoorbeeld in Kladblok ziet u het allemaal als één lange regel. Verander de code hierin om de juiste nieuwe regels te hebben:
string csv = string.Format("{0},{1}{2}", first, image, Environment.NewLine);
Antwoord 7, autoriteit 3%
In plaats van het wiel opnieuw uit te vinden, zou een bibliotheek kunnen worden gebruikt. CsvHelper
is geweldig voor het maken en lezen van csv-bestanden. De lees- en schrijfbewerkingen zijn gebaseerd op streams en ondersteunen daarom ook bewerkingen met een grote hoeveelheid gegevens.
U kunt uw csv als volgt schrijven.
using(var textWriter = new StreamWriter(@"C:\mypath\myfile.csv"))
{
var writer = new CsvWriter(textWriter, CultureInfo.InvariantCulture);
writer.Configuration.Delimiter = ",";
foreach (var item in list)
{
writer.WriteField( "a" );
writer.WriteField( 2 );
writer.WriteField( true );
writer.NextRecord();
}
}
Omdat de bibliotheek reflectie gebruikt, zal het elk type nemen en het direct ontleden.
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, CultureInfo.InvariantCulture);
writer.Configuration.Delimiter = ",";
writer.WriteRecords(rows);
}
waarde1,waar
waarde2, onwaar
Als je meer wilt lezen over de configuraties en mogelijkheden van de bibliotheek, kun je dat hierdoen.
Antwoord 8, autoriteit 2%
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();
}
}
}
}
}
}
Antwoord 9
Omgaan met komma’s
Voor het verwerken van komma’s binnen waarden bij het gebruik van string.Format(...)
, heeft het volgende voor mij gewerkt:
var newLine = string.Format("\"{0}\",\"{1}\",\"{2}\"",
first,
second,
third
);
csv.AppendLine(newLine);
Dus om het te combineren met het antwoord van Johan, zou het er als volgt uitzien:
//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-bestand retourneren
Als je het bestand gewoon wilt retourneren in plaats van het naar een locatie te schrijven, is dit een voorbeeld van hoe ik het heb gedaan:
Van een opgeslagen procedure
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");
}
Uit een lijst
/* 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");
}
Hopelijk is dit nuttig.
Antwoord 10
Dit is een eenvoudige tutorial over het maken van CSV-bestanden met C # waarmee u kunt bewerken en uitbreiden op uw eigen behoeften.
Eerst moet je een nieuwe visuele studio C # console-applicatie maken, er zijn stappen om dit te doen.
De voorbeeldcode maakt een CSV-bestand met de naam MyTest.CSV op de locatie die u opgeeft. De inhoud van het bestand moet 3 genoemde kolommen zijn met tekst in de eerste 3 rijen.
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);
}
}
}
Antwoord 11
Misschien moet u gewoon een regelfeed toevoegen "\n\r"
.
Antwoord 12
Hier is nog een open source-bibliotheek om eenvoudig een CSV-bestand te maken, 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);
}
Lees voor meer informatie het artikel CodeProjectop gebruik.
Antwoord 13
Een eenvoudige manier om van het overschrijfprobleem af te komen, is door File.AppendText
te gebruiken om een regel aan het einde van het bestand toe te voegen als
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);
}
}
Antwoord 14
enter code here
string string_value= string.Leeg;
for (int i = 0; i < ur_grid.Rows.Count; i++)
{
for (int j = 0; j < ur_grid.Rows[i].Cells.Count; j++)
{
if (!string.IsNullOrEmpty(ur_grid.Rows[i].Cells[j].Text.ToString()))
{
if (j > 0)
string_value= string_value+ "," + ur_grid.Rows[i].Cells[j].Text.ToString();
else
{
if (string.IsNullOrEmpty(string_value))
string_value= ur_grid.Rows[i].Cells[j].Text.ToString();
else
string_value= string_value+ Environment.NewLine + ur_grid.Rows[i].Cells[j].Text.ToString();
}
}
}
}
string where_to_save_file = @"d:\location\Files\sample.csv";
File.WriteAllText(where_to_save_file, string_value);
string server_path = "/site/Files/sample.csv";
Response.ContentType = ContentType;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(server_path));
Response.WriteFile(server_path);
Response.End();
Antwoord 15
public static class Extensions
{
public static void WriteCSVLine(this StreamWriter writer, IEnumerable<string> fields)
{
const string q = @"""";
writer.WriteLine(string.Join(",",
fields.Select(
v => (v.Contains(',') || v.Contains('"') || v.Contains('\n') || v.Contains('\r')) ? $"{q}{v.Replace(q, q + q)}{q}" : v
)));
}
public static void WriteFields(this StreamWriter writer, params string[] fields) => WriteFields(writer, (IEnumerable<string>)fields);
}
Hiermee zou je heel eenvoudig een csv-bestand moeten kunnen schrijven. Gebruik:
StreamWriter writer = new StreamWriter("myfile.csv");
writer.WriteCSVLine(new[]{"A", "B"});