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);
}
Возможно, стоит также отправить заголовок содержимого с рекомендуемым именем файла.
Редактировать: В последнее время в случаях, когда необходимо пересечь действие между элементами в перечислении (например, запятая и новая строка выше), я предпочел, чтобы, скорее, сохраняя логическое значение, которое продолжает проверяться, я обрабатываю перечислитель напрямую, а затем обрабатывать первый элемент отдельно от остальных. Я начал делать это как микроопт в эффективном нажатии, но вырос, чтобы просто найти лучшее выражение для кода, который отличается для первого элемента.Таким образом, я сейчас пишу выше, как:
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);
}
}
}
После прочтения. Все, что мне действительно нужно сделать, это цикл и вывод данных, разделенных запятыми, с/n в конце строки и продолжением цикла до завершения ... сохранить файл как .csv, а затем закрыть поток ... правильно? – Tom
Вам также необходимо установить тип содержимого, и если в базе данных может содержаться символ '' ',', 'или символ новой строки, вам также необходимо его избежать. Код для этого в моем ответе. –