private void WriteItem<T>(StreamWriter sr, T item)
{
string itemString = item.ToString();
if(itemString.IndexOfAny(new char[] { '"', ',', '\n', '\r' }) != -1)//skip test and always escape for different speed/filesize optimisation
{
sr.Write('"');
sr.Write(itemString.Replace("\"", "\"\""));
sr.Write('"');
}
else
sr.Write(itemString);
}
private void WriteLine<T>(StreamWriter sr, IEnumerable<T> line)
{
bool first = true;
foreach(T item in line)
{
if(!first)
sr.Write(',');
first = false;
WriteItem(sr, item);
}
}
private void WriteCSV<T>(StreamWriter sr, IEnumerable<IEnumerable<T>> allLines)
{
bool first = true;
foreach(IEnumerable<T> line in allLines)
{
if(!first)
sr.Write('\n');
first = false;
WriteLine(sr, line);
}
}
private void WriteCSV<T>(HttpResponse response, IEnumerable<IEnumerable<T>> allLines)
{
response.ContentType = "text/csv";
WriteCSV(response.Output, allLines);
}
Warto również wysłać nagłówek treści z rekomendowaną nazwą pliku.
Edycja: Ostatnio, w przypadkach, w których trzeba przeplatać akcję między elementami w wyliczeniu (jak przecinek i znak nowej linii powyżej), wolałbym raczej zachować wartość boolowską, która jest ciągle sprawdzana, obsługuję moduł wyliczający bezpośrednio, a następnie obsłużyć pierwszy element oddzielony od reszty. Zacząłem robić to jako mikro-opt w pchnięciu efektywności, ale urosłem, aby znaleźć lepszy wyraz ścieżki kodu, która różni się dla pierwszego przedmiotu.Jako takie, bym teraz napisać jak wyżej:
private void WriteLine<T>(StreamWriter sr, IEnumerable<T> line)
{
using(var en = line.GetEnumerator())
if(en.MoveNext())
{
WriteItem(sr, en.Current);
while(en.MoveNext())
{
sr.Write(',');
WriteItem(sr, en.Current);
}
}
private void WriteCSV<T>(StreamWriter sr, IEnumerable<IEnumerable<T>> allLines)
{
using(var en = allLines.GetEnumerator())
if(en.MoveNext())
{
WriteLine(sr, en.Current);
while(en.MoveNext())
{
sr.Write('\n');
WriteLine(sr, en.Current);
}
}
}
Po lekturze. Wszystko, co naprawdę muszę zrobić, to przejrzeć dane wyjściowe i oddzielić je przecinkami z/n na końcu wiersza i przechodzić dalej aż do zrobienia ... zapisać plik jako .csv, a następnie zamknąć strumień ... poprawny? – Tom
Musisz również ustawić typ zawartości, a jeśli baza danych może zawierać znak "", ',' lub znak nowej linii, musisz również uciec. Kod dla tego w mojej odpowiedzi –