Подтвердить что ты не робот

Запись CSV файла в .net

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

Я потратил некоторое время на поиск набора правил и понял, что существует множество правил и исключений при записи 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-писателя либо стороннего, либо (надеюсь,!), включенных в структуру .net.

Изменить: Новая ссылка: http://www.thinqlinq.com/Post.aspx/Title/LINQ-to-CSV-using-DynamicObject-and-TextFieldParser

TextFieldParser - это объект VB (на который можно ссылаться на С#), который будет автоматически анализировать файлы 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-to-CSV (а не фрейм-библиотека): http://www.codeproject.com/KB/linq/LINQtoCSV.aspx

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

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

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

4b9b3361

Ответ 1

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

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, и вы должны быть в порядке (например, yyyy-mm-dd hh: mm: ss)

Ответ 2

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

Ответ 3

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

Ответ 4

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

Ответ 5

Вот функция, которую вы можете использовать для создания строки 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 в С# не составит труда

Ответ 7

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

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

Ответ 8

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

Ответ 9

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

Ответ 10

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

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

Более внимательно, эта реализация по существу использует только базовые правила:

специальные символы =\n\"и разделитель char.

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

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

Ответ 11

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

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