2009-11-06 3 views
41

У меня есть требование экспортировать набор данных в виде файла CSV.Запись CSV-файла в .net

Я потратил некоторое время на поиск набора правил и понял, что существует множество правил и исключений при записи CSV-файла.

http://knab.ws/blog/index.php?/archives/3-CSV-file-parser-and-writer-in-C-Part-1.html http://bytes.com/topic/c-sharp/answers/236875-problems-streamwriter-output-csv http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/0073fcbb-adab-40f0-b768-4bba803d3ccd

Так что теперь это не простой процесс разделения строк с запятыми, я искал существующий CSV писатель либо 3 партии или (надеюсь!), Включенный в рамках .net.

Edit: Новая ссылка: http://www.thinqlinq.com/Post.aspx/Title/LINQ-to-CSV-using-DynamicObject-and-TextFieldParser

TextFieldParser является объектом VB (можно ссылаться из C#), который будет автоматически анализировать CSV-файлы. :)

Мне было интересно, если кто-нибудь знает какие-нибудь удобные библиотеки .Net (2.0 -> 3.5 и 4.0), которые могут быть использованы для создания правильно отформатированного CSV-файла.

Также, если есть какие-либо наборы правил для генерации CSV-файлов.

Есть много деталей чтения CSV и анализа CSV-файлов, но не так много о написании (хорошо, я знаю, что это просто противоположность: P).

http://www.codeproject.com/KB/database/CsvReader.aspx

Любая помощь будет высоко ценится :)

я нашел еще одну статью с некоторыми более подробными правилами CSV: http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm

Аккуратный третья библиотека партия является Linq к CSV (не рамочная библиотека): http://www.codeproject.com/KB/linq/LINQtoCSV.aspx

Спасибо за вашу помощь. Я решил, что лучшим решением будет создание простого статического класса, который будет выполнять специальную замену персонажа (что упоминал Крис).

Если у меня возникла необходимость в Linq, запрашивающей мои CSV-файлы, я бы посмотрел на реализацию CodeProjects Linq-to-CSV.

Еще раз спасибо :)

+0

Я думаю, что, поскольку вы являетесь экспортером, вы можете быть довольно расслабленным, когда пишете, если вы просто следуете общим правилам, большинство таких программ, как Excel, определяют, как их читать. –

+0

Это правда. Я нахожусь в неудачной позиции написания функции «Экспорт», которая не указывает на потенциальное использование. Я предполагаю, что в 99% случаев это будет превосходить или, возможно, (маловероятно) пакеты SSIS другими приложениями.Я могу только предположить. – Russell

+0

Вы можете попробовать мой очень легкий разделитель файлов: https://gist.github.com/eranbetzalel/5371817#file-delimitedfilewriter-cs –

ответ

22

Если есть какие-либо запятые в своей камере, окружает всю клетку с двойными кавычками, например:

cell 1,cell 2,"This is one cell, even with a comma",cell4,etc 

И если вы хотите буквальные двойные кавычки, сделать два из них, например:

cell 1,cell 2,"This is my cell and it has ""quotes"" in it",cell 4,etc 

Что касается даты, придерживаться формата ISO, и вы должны быть хорошо (например, гггг-мм-дд чч: мм: сс)

+2

Являются ли они единственными «правилами» как таковыми? Например, о новых линиях. Знаете ли вы какие-либо ссылки на эти правила/требования? Я предполагаю (из поисков), что для этих типов файлов нет стандарта, просто требуются проприетарные требования (например, что будет работать с excel: P). Спасибо за ваш вклад. – Russell

+0

В принципе, я иду с любыми работами с excel. Что касается новых строк, различные функции AppendLine и WriteLine C# кажутся append \ r \ n, что, похоже, согласуется с excel. – Chris

+0

И не забудьте указать значения с символами новой строки в двойных кавычках. –

6

Я использовал filehelpers широко, и это довольно удивительным для создания томов CSV.

+0

Спасибо, FileHelpers выглядит как очень удобная (+ open-source) библиотека. К сожалению, в этом случае я не могу добавить атрибуты к моим объектам, которые я хотел бы преобразовать в CSV. Используя рефлектор .net, я не мог понять, как это сделать, передавая значения/списки. Вы знаете, возможно ли это? – Russell

+0

Вы могли бы просто создать несколько новых «только для генераторов» классов и использовать AutoMapper для сопоставления реальных классов с классами генераторов, а затем писать эти классы с помощью FileHelpers. Я сделал это раньше, и это довольно просто. – lomaxx

+0

Действительно ли файловый сервер действительно CSV? Конечно, у них есть разделители, но это не то же самое, что CSV с правилами котировки. –

2

вы можете использовать ODBC для чтения и записи CSV-файлов (с помощью OdbcConnection и подходящий строка подключения).Это должно быть разумно полезно для создания CSV-файлов и будет обрабатывать такие вещи, как цитирование для вас; однако я столкнулся с некоторыми проблемами при его использовании для чтения CSV-файлов, созданных другими программами.

+1

Спасибо, есть ли какие-либо ссылки для начала этого метода? – Russell

+1

Если вы google для «файла ccv odbc», он создает несколько ссылок. Верхний - это http://www.c-sharpcorner.com/UploadFile/mahesh/AccessTextDb12052005071306AM/AccessTextDb.aspx - обратите внимание, что вам нужно прокрутить путь вниз, чтобы найти код C#! – itowlson

0

Я нашел эту важную ссылку, которая довольно аккуратная. Еще не пробовал, даст вам знать, как это происходит!

http://www.codeproject.com/KB/linq/LINQtoCSV.aspx

Присмотревшись, эта реализация в основном использует только основные правила тоже:

спецсимволы = \ п \»и разделитель полукокса

если найдены специальные символы, то окружают. цитаты Заменить цитату с двойной цитатой.

По существу, правила, упомянутые Крисом. Я думаю, что самый простой способ сделать это - создать e мой вспомогательный метод, основанный на простых правилах и пересматривающий на основе потребностей пользователей.

2

Другое правило для добавления к другим: используйте запятые как разделители полей, а не как терминаторы полей. Причина этого в том, что конечная запятая в конце строки может быть неоднозначной: не имеет ли значение или означает ли она значение NULL после нее?

+0

Очень хорошая точка. Было бы неплохо иметь разделитель «end-of-row» вместо того, чтобы принимать новую строку. Например, разные ОС используют разные символы! – Russell

+1

Формат CSV определяет CRLF ("\ r \ n") как ограничитель для каждой строки. – Gusdor

3

Я знаю, что вы сказали, что вы нашли ответ на свой вопрос, но я просто хотел, чтобы дать голос для библиотеки LINQtoCSV вы упомянули. Я использовал его в нескольких проектах, и он отлично работает для того, чтобы ваш бизнес-код был чистым и не касался деталей/особенностей формата файла.

Возможно, в вашем конкретном случае писать экспортера не так уж сложно, но приятная вещь об этой библиотеке заключается в том, что она двунаправленная. Если вам приходится потреблять CSV по дороге, это не намного лишний код, и/или он дает вам согласованную библиотеку для использования в будущих проектах.

+0

Спасибо, это выглядит очень удобно. Проекты имеют разные требования и приоритеты, поэтому различные решения могут лучше соответствовать различным проектам. Спасибо и не забудьте проголосовать, если вам это нравится. :) – Russell

18

Я бы просто хотел добавить, что есть RFC, который определяет формат CSV, который я бы рассматривал как канонический источник.

+1

Спасибо, Ричард, это очень подробная информация :) – Russell

46

CsvHelper (библиотека, которую я поддерживаю) также доступна через NuGet.

CsvHelper может автоматически записывать объекты класса в файл для вас.

var myObj = new MyCustomClass 
{ 
    Prop1 = "one", 
    Prop2 = 2 
}; 
var streamWriter = // Create a writer to somewhere... 
var csvWriter = new CsvWriter(streamWriter); 

// You can write a single record. 
csvWriter.WriteRecord(myObj); 

// You can also write a collection of records. 
var myRecords = new List<MyCustomClass>{ myObj }; 
csvWriter.WriteRecords(myRecords); 
+0

Кстати, в CsvHelper добавлены некоторые функции отображения, которые позволяют вам сопоставлять классы без использования атрибутов. Вместо этого вы можете использовать свободный класс сопоставления, который позволяет вам сопоставлять классы, на которые у вас нет контроля. –

+0

csvhelper очень хороший. –

+0

Именно то, что я искал и люблю! Благодарю. –

0

Вы можете использовать массив строк, а затем сцепить с помощью:

string out = ""; 
string[] elements = { "1", "2" }; 
foreach(string s in elements) { out += s + "," }; 
out = out.substring(0, out.Length-1); 
+1

вы можете заменить вышеуказанный код на String.Join (",", "1", "2", "etc ..."); – AndyD

4

Вот функция, которую можно использовать для генерации строки CSV файла из списка строк (IEnumerable (Of String) или строка массив может быть использован, а):

Function CreateCSVRow(strArray As List(Of String)) As String 
    Dim csvCols As New List(Of String) 
    Dim csvValue As String 
    Dim needQuotes As Boolean 
    For i As Integer = 0 To strArray.Count() - 1 
     csvValue = strArray(i) 
     needQuotes = (csvValue.IndexOf(",", StringComparison.InvariantCulture) >= 0 _ 
         OrElse csvValue.IndexOf("""", StringComparison.InvariantCulture) >= 0 _ 
         OrElse csvValue.IndexOf(vbCrLf, StringComparison.InvariantCulture) >= 0) 
     csvValue = csvValue.Replace("""", """""") 
     csvCols.Add(If(needQuotes, """" & csvValue & """", csvValue)) 
    Next 
    Return String.Join(",", csvCols.ToArray()) 
End Function 

Как я думаю, это не будет трудно конвертировать из VB.NET в C#)

+0

Спасибо за информацию Евгения, я уверен, что это будет полезно для тех, кто сталкивается с этим вопросом. :) – Russell

Смежные вопросы