2012-06-15 21 views
15

Làm cách nào tôi có thể viết tất cả các giá trị (thuộc tính) vào chuỗi được định dạng csv trong C#? ví dụ:Thực thể đối tượng để tuần tự hóa/chuyển đổi CSV

class Person(string firstName, string lastName, int_age); 
Person person = new Person("Kevin","Kline",33); 

bây giờ tôi muốn có một chuỗi "Kevin; Kline; 33"

Nói cách khác tôi muốn serialize một đối tượng vào CSV

+4

giá trị của cái gì? –

+0

Câu hỏi của bạn cần nhiều nền tảng hơn và ví dụ về dữ liệu/mã để tránh bị ứng cử viên đóng cửa. –

+1

Bạn có thể cho chúng tôi thấy những gì bạn đã thử không? – LolCat

Trả lời

2

bạn có thể sử dụng một cái gì đó như thế này:

... 
     PropertyInfo[] properties = obj.GetType().GetProperties(); 
     string CSVRow = ""; 
     foreach (PropertyInfo pi in properties) 
     { 
      CSVRow = CSVRow + pi.GetValue(obj, null) + ";"; 
     } 
     CSVRow.Remove(CSVRow.Length - 1, 1); 
... 
+3

... nhưng cũng cần triển khai quy tắc trích dẫn/thoát. – Joe

0

Something như thế này:

public string ToCsv() 
{ 
    return string.Join(";", new string[]{ 
     _firstName, 
     _lastName, 
     _age.ToString() 
    }.Select(str=>Escape(str))); 
} 

Hoặc, sử dụng phản chiếu,

public static string ToCsv(this object obj) 
{ 
    return string.Join(";", 
     this.GetType().GetProperties().Select(pi=> 
      Escape(pi.GetValue(this, null).ToString()) 
     )); 
} 

đâu Escape là một chức năng thoát thích hợp.

9

Bằng cách sử dụng phản ánh bạn có thể lấy các infos tài sản từ một đối tượng

foreach (PropertyInfo prp in obj.GetType().GetProperties()) { 
    if (prp.CanRead) { 
     object value = prp.GetValue(obj, null); 
     string s = value == null ? "" : value.ToString(); 
     string name = prp.Name; 
     ... 
    } 
} 

Phương pháp GetProperties có tình trạng quá tải chấp nhận BindingFlags thông qua đó bạn có thể xác định loại tài sản mà bạn cần, như tin dụ/public/tĩnh .

Bạn có thể kết hợp chúng như thế này

var properties = type.GetProperties(BindingFlags.Public | 
            BindingFlags.NonPublic | 
            BindingFlags.Instance); 

Áp dụng cho vấn đề của bạn, bạn có thể viết

List<Person> people = ...; 
Type type = typeof(Person); 
PropertyInfo[] properties = type.GetProperties(); 
var sb = new StringBuilder(); 

// First line contains field names 
foreach (PropertyInfo prp in properties) { 
    if (prp.CanRead) { 
     sb.Append(prp.Name).Append(';'); 
    } 
} 
sb.Length--; // Remove last ";" 
sb.AppendLine(); 

foreach (Person person in people) { 
    foreach (PropertyInfo prp in properties) { 
     if (prp.CanRead) { 
      sb.Append(prp.GetValue(person, null)).Append(';'); 
     } 
    } 
    sb.Length--; // Remove last ";" 
    sb.AppendLine(); 
} 

File.AppendAllText("C:\Data\Persons.csv", sb.ToString()); 

Nó cũng là một ý tưởng tốt để kèm theo chuỗi trong dấu ngoặc kép và để thoát khỏi đôi báo giá chúng chứa bằng cách tăng gấp đôi chúng.

13

Có một cái nhìn tại Josh Close's tuyệt vời CSVHelper thư viện

var person = new Person("Kevin","Kline",33); 
using (var csv = new CsvWriter(new StreamWriter("file.csv"))) 
{ 
    csv.Configuration.HasHeaderRecord = false; 
    csv.Configuration.Delimiter = ';'; 
    csv.WriteRecord(person); 
} 

Output:

Kevin;Kline;33 
+0

Có thể sử dụng CSVHelper mà không cần phần lưu file.csv không? Tôi không muốn ghi tệp trong tệp HD, tôi định gửi tệp dưới dạng phản hồi cho người dùng web. – Lombas

+4

Phần tốt nhất là nó có sẵn cho .Net Core –

2

Tôi tin FileHelpers là tốt cho điều này, tôi đã không sử dụng nó trong sự tức giận bản thân mình mặc dù

+0

Nó là tốt. Quá xấu nó không làm việc cho. Net Core mặc dù:/CSVHelper nào !! –

0

Một thực hiện có thể cho bạn, mà đọc các đối tượng phức tạp (serialization đối tượng sâu), giống như mảng các đối tượng với các thuộc tính được arr ay đối tượng và lưu o chuỗi được định dạng như tệp CSV:

private string ToCsv(string separator, IEnumerable<object> objectList) 
{ 
    StringBuilder csvData = new StringBuilder(); 
    foreach (var obj in objectList) 
    { 
     csvData.AppendLine(ToCsvFields(separator, obj)); 
    } 
    return csvData.ToString(); 
} 

private string ToCsvFields(string separator, object obj) 
{ 
    var fields = obj.GetType().GetProperties(); 
    StringBuilder line = new StringBuilder(); 

    if (obj is string) 
    { 
     line.Append(obj as string); 
     return line.ToString(); 
    } 

    foreach (var field in fields) 
    { 
     var value = field.GetValue(obj); 
     var fieldType = field.GetValue(obj).GetType(); 

     if (line.Length > 0) 
     { 
      line.Append(separator); 
     } 
     if (value == null) 
     { 
      line.Append("NULL"); 
     } 
     if (value is string) 
     { 
      line.Append(value as string); 
     } 
     if (typeof(IEnumerable).IsAssignableFrom(fieldType)) 
     { 
      var objectList = value as IEnumerable; 
      StringBuilder row = new StringBuilder(); 

      foreach (var item in objectList) 
      { 
       if (row.Length > 0) 
       { 
        row.Append(separator); 
       } 
       row.Append(ToCsvFields(separator, item)); 
      } 
      line.Append(row.ToString()); 
     } 
     else 
     { 
      line.Append(value.ToString()); 
     } 
    } 
    return line.ToString(); 
} 
Các vấn đề liên quan