2009-11-06 46 views
41

Tôi có yêu cầu xuất tập dữ liệu dưới dạng tệp CSV.Viết tệp CSV bằng .net

Tôi đã dành một lúc để tìm kiếm một bộ quy tắc để đi qua và nhận ra có một vài quy tắc và ngoại lệ khi viết tệp 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

Vì vậy, bây giờ nó không phải là một quá trình đơn giản tách chuỗi bằng dấu phẩy, tôi đã tìm kiếm một nhà văn CSV hiện một trong hai bên thứ 3 hoặc (hy vọng!) Nằm trong khuôn khổ .net.

Chỉnh sửa: New link: http://www.thinqlinq.com/Post.aspx/Title/LINQ-to-CSV-using-DynamicObject-and-TextFieldParser

Các TextFieldParser là một đối tượng VB (có thể được tham chiếu từ C#) sẽ tự động phân tích cú pháp file CSV. :)

Tôi đã tự hỏi liệu có ai biết bất kỳ thư viện .Net (2.0 -> 3.5 và 4.0) tiện dụng nào có thể được sử dụng để tạo tệp CSV được định dạng chính xác hay không.

Ngoài ra, nếu có bất kỳ bộ quy tắc nào để tạo tệp CSV.

Có rất nhiều chi tiết của trình đọc CSV và phân tích cú pháp tệp CSV, tuy nhiên không nhiều về viết (ok, tôi biết nó chỉ là đối diện: P).

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

Bất kỳ trợ giúp sẽ được nhiều đánh giá cao :)

Tôi tìm thấy một bài viết với một số quy tắc CSV chi tiết hơn: http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm

Một thư viện của bên thứ 3 gọn gàng là LINQ-to-CSV (không phải thư viện khung): http://www.codeproject.com/KB/linq/LINQtoCSV.aspx

Cảm ơn sự giúp đỡ của mọi người. Tôi đã quyết định rằng giải pháp tốt nhất là tạo một lớp tĩnh đơn giản sẽ thực hiện thay thế ký tự đặc biệt (mà Chris đã đề cập).

Nếu tôi cần LINQ truy vấn tệp CSV của mình, tôi sẽ xem xét việc triển khai CodeProjects của LINQ-to-CSV.

Cảm ơn bạn lần nữa :)

+0

Tôi nghĩ rằng kể từ khi bạn là một trong những xuất khẩu, bạn có thể được khá thoải mái khi bạn viết, nếu bạn chỉ cần làm theo các quy tắc chung hầu hết các chương trình như Excel tìm ra cách để đọc chúng. –

+0

Đúng vậy. Tôi ở vị trí không may khi viết chức năng "Xuất" mà không chỉ định sử dụng tiềm năng. Tôi cho rằng 99% thời gian này sẽ là gói excel hoặc có lẽ (không) SSIS bởi các ứng dụng khác.Tôi chỉ có thể giả định. – Russell

+0

Bạn có thể thử trình soạn thảo tập tin có giới hạn trọng lượng rất nhẹ: https://gist.github.com/eranbetzalel/5371817#file-delimitedfilewriter-cs –

Trả lời

22

Nếu có bất kỳ dấu phẩy trong di động của bạn, bao quanh toàn bộ tế bào với dấu ngoặc kép, ví dụ:

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

Và nếu bạn muốn có một dấu nháy kép theo nghĩa đen, làm hai người bọn họ, ví dụ:

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

đối với ngày tháng, dính sang định dạng ISO, và bạn nên sử dụng tốt (ví dụ yyyy-mm-dd hh: mm: ss)

+2

Chúng là "quy tắc" duy nhất cho mỗi người? Ví dụ về dòng mới. Bạn có biết bất kỳ tài liệu tham khảo cho các quy tắc/requirments? Tôi giả định (từ các tìm kiếm) rằng không có tiêu chuẩn cho các loại tệp này, chỉ các yêu cầu về sở hữu (ví dụ: những gì sẽ làm việc với excel: P). Cảm ơn vì đầu vào của bạn. – Russell

+0

Về cơ bản, tôi đi với bất cứ điều gì làm việc với excel. Đối với các dòng mới, các hàm AppendLine và WriteLine khác nhau của C# dường như nối thêm \ r \ n, có vẻ như đồng ý với excel. – Chris

+0

Và hãy nhớ để kèm theo các giá trị với newlines trong dấu ngoặc kép. –

6

Tôi đã sử dụng rộng rãi filehelpers và thật tuyệt vời khi tạo CSV.

+0

Cảm ơn, FileHelpers trông giống như một thư viện (nguồn mở) rất tiện dụng. Thật không may trong trường hợp này tôi không thể thêm thuộc tính cho các đối tượng của tôi mà tôi muốn chuyển đổi thành CSV. Sử dụng .net phản xạ Tôi không thể nhìn thấy một cách để làm điều này bằng cách đi qua trong các giá trị/danh sách. Bạn có biết nếu điều này là có thể? – Russell

+0

Bạn chỉ có thể tạo một số lớp "máy phát duy nhất" mới và sử dụng AutoMapper để ánh xạ các lớp thực của bạn tới các lớp máy phát và sau đó viết các lớp đó ra bằng FileHelpers. Tôi đã thực hiện nó trước và nó khá đơn giản. – lomaxx

+0

Filehelpers có thực sự làm CSV không? Chắc chắn họ có Delimited nhưng đó không giống như CSV với các quy tắc báo giá. –

2

bạn có thể sử dụng ODBC để đọc và ghi tập tin CSV (thông qua OdbcConnection và phù hợp chuỗi kết nối).Điều này sẽ hợp lý để tạo tệp CSV và sẽ xử lý những thứ như trích dẫn cho bạn; tuy nhiên tôi đã gặp phải một số vấn đề khi sử dụng nó để đọc các tệp CSV do các chương trình khác tạo ra.

+1

Cảm ơn, có bất kỳ tham chiếu nào để bắt đầu cho phương pháp này không? – Russell

+1

Nếu bạn google cho "odbc csv file", nó sẽ tạo ra một vài liên kết tốt. Đầu trang là http://www.c-sharpcorner.com/UploadFile/mahesh/AccessTextDb12052005071306AM/AccessTextDb.aspx - lưu ý rằng bạn sẽ cần phải cuộn xuống phía dưới để tìm mã C# mặc dù! – itowlson

0

Tôi tìm thấy liên kết quan trọng này khá gọn gàng. Chưa thử nó, sẽ cho bạn biết làm thế nào nó đi!

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

Nhìn kỹ hơn, thực hiện này chủ yếu chỉ sử dụng quy tắc cơ bản quá:

đặc biệt chars = \ n \" và tách char

nếu tìm thấy ký tự đặc biệt, sau đó vòm với. Thay thế báo giá bằng dấu ngoặc kép.

Về cơ bản các quy tắc mà Chris đã đề cập. Tôi nghĩ cách dễ nhất để làm điều này là tạo e phương thức trợ giúp của tôi dựa trên các quy tắc đơn giản và sửa đổi trên cơ sở nhu cầu của người dùng.

2

Quy tắc khác để thêm vào các quy tắc khác: Sử dụng dấu phẩy làm dấu phân cách trường thay vì làm dấu phân cách trường. Lý do cho điều này là dấu phẩy ở cuối dòng có thể mơ hồ: Liệu nó không có ý nghĩa hay nó biểu thị một giá trị NULL sau nó?

+0

Điểm rất tốt. Nó sẽ là tốt đẹp để có một "end-of-hàng" tách thay vì giả định một dòng mới. Ví dụ hệ điều hành khác nhau sử dụng các nhân vật khác nhau! – Russell

+1

Định dạng CSV chỉ định CRLF ("\ r \ n") làm trình kết thúc cho mỗi hàng. – Gusdor

3

Tôi biết bạn nói bạn tìm thấy câu trả lời của bạn, nhưng tôi chỉ muốn cung cấp cho một cuộc bỏ phiếu cho các thư viện LINQtoCSV bạn đề cập đến. Tôi đã sử dụng nó trong một vài dự án và nó hoạt động thực sự tốt để giữ mã doanh nghiệp của bạn sạch sẽ và không quan tâm đến chi tiết/tính đặc thù của định dạng tệp.

Có thể trong trường hợp cụ thể của bạn không quá khó để viết nhà xuất khẩu, nhưng điều tốt đẹp về thư viện này là nó là hai chiều. Nếu bạn thấy mình phải tiêu thụ CSV xuống đường thì nó không phải là mã bổ sung, và/hoặc nó cung cấp cho bạn một thư viện nhất quán để sử dụng cho các dự án trong tương lai.

+0

Cảm ơn, nó trông rất tiện dụng thực sự. Các dự án có các yêu cầu và ưu tiên khác nhau để các giải pháp khác nhau có thể phù hợp hơn với các dự án khác nhau. Cảm ơn và không quên bỏ phiếu nếu bạn thích nó. :) – Russell

18

Tôi chỉ muốn thêm có một số RFC chỉ định định dạng CSV mà tôi coi là nguồn chuẩn tắc.

+1

Cảm ơn Richard, đó là một thông tin rất chi tiết :) – Russell

46

CsvHelper (thư viện tôi duy trì) cũng có sẵn qua NuGet.

CsvHelper có thể tự động viết đối tượng lớp của bạn vào tệp cho bạn.

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

Btw, đã có một số tính năng ánh xạ được thêm vào CsvHelper cho phép bạn ánh xạ các lớp của mình mà không cần sử dụng các thuộc tính. Thay vào đó, bạn có thể sử dụng lớp ánh xạ thành thạo, cho phép bạn ánh xạ tới các lớp mà bạn không có quyền kiểm soát. –

+0

csvhelper rất tốt. –

+0

Chính xác những gì tôi đang tìm kiếm và yêu thích nó! Cảm ơn. –

0

Bạn có thể sử dụng một mảng chuỗi và sau đó tiếp nhau sử dụng:

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

bạn có thể thay thế mã ở trên bằng String.Join (",", "1", "2", "v.v ..."); – AndyD

4

Dưới đây là chức năng bạn có thể sử dụng để tạo ra một hàng của tệp CSV từ danh sách chuỗi (IEnumerable (Tất String) hoặc chuỗi mảng có thể được sử dụng như là tốt):

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 

theo tôi nghĩ, nó sẽ không khó khăn để chuyển đổi từ VB.NET sang C#)

+0

Cảm ơn thông tin Evgeny, tôi chắc chắn nó sẽ hữu ích cho một người đi qua câu hỏi này. :) – Russell

Các vấn đề liên quan