2013-07-17 14 views
6

Mam listę, którą chcę napisać do ciągu CSV.Ogólna lista do ciągu CSV

Przykłady, które znalazłem wszystkie wydają się być dla pojedynczych list przedmiotów, moje ma wiele przedmiotów.

Obecny kod to;

private static string CreateCSVTextFile<T>(List<T> data, string seperator = ",") where T : ExcelReport, new() 
{ 
    var objectType = typeof(T); 
    var properties = objectType.GetProperties(); 
    var currentRow = 0; 
    var returnString = ""; 
    foreach (var row in data) 
    { 
    var currentColumn = 0; 
    var lineString = ""; 
    foreach (var info in properties) 
    { 
     lineString = lineString + info.GetValue(row, null) + seperator; 
     currentColumn++; 
    } 
    if (seperator != "") 
    { 
     lineString = lineString.Substring(0, lineString.Count() - 2); 
    } 
    returnString = returnString + Environment.NewLine + lineString; 
    currentRow++; 
    } 
    return returnString; 
} 

Ale kiedy lista jest duża, ta metoda trwa bardzo długo.

Klasa, której moja lista opiera się na wyglądzie;

internal class ClientMasterFile 
{ 
public String COL1{ get; set; } 
public String COL2{ get; set; } 
public String COL3{ get; set; } 
public String COL4{ get; set; } 
public String COL5{ get; set; } 
public String COL6{ get; set; } 
public String COL7{ get; set; } 
public String COL8{ get; set; } 
public String COL9{ get; set; } 
public String COL10{ get; set; } 
public String COL11{ get; set; } 
public String COL12{ get; set; } 
} 

Czy jest szybszy sposób to zrobić przy użyciu zaawansowanej wersji String.Join?

Dzięki

+3

Używasz ciąg konkatenacji. Użyj 'StringBuilder'. – Romoku

+2

Utwórz nadpisanie metody ToString() w swoim ClientMasterFile i nie będziesz potrzebować Reflection, ponieważ to zajmuje tak dużo czasu. –

Odpowiedz

17

Twój sposób można uprościć stosując StringBuilder i string.Join.

Łączenie ciągów bezpośrednio jest powolne i wymaga dużej ilości pamięci, co jest dobre dla małych operacji.

Patrz: Does StringBuilder use more memory than String concatenation?

private static string CreateCSVTextFile<T>(List<T> data, string seperator = ",") 
{ 
    var properties = typeof(T).GetProperties(); 
    var result = new StringBuilder(); 

    foreach (var row in data) 
    { 
     var values = properties.Select(p => p.GetValue(row, null)); 
     var line = string.Join(seperator, values); 
     result.AppendLine(line); 
    } 

    return result.ToString(); 
} 

Pełniejszy Implementacja pliki CSV:

private static string CreateCSVTextFile<T>(List<T> data) 
{ 
    var properties = typeof(T).GetProperties(); 
    var result = new StringBuilder(); 

    foreach (var row in data) 
    { 
     var values = properties.Select(p => p.GetValue(row, null)) 
           .Select(v => StringToCSVCell(Convert.ToString(v))); 
     var line = string.Join(",", values); 
     result.AppendLine(line); 
    } 

    return result.ToString(); 
} 

private static string StringToCSVCell(string str) 
{ 
    bool mustQuote = (str.Contains(",") || str.Contains("\"") || str.Contains("\r") || str.Contains("\n")); 
    if (mustQuote) 
    { 
     StringBuilder sb = new StringBuilder(); 
     sb.Append("\""); 
     foreach (char nextChar in str) 
     { 
      sb.Append(nextChar); 
      if (nextChar == '"') 
       sb.Append("\""); 
     } 
     sb.Append("\""); 
     return sb.ToString(); 
    } 

    return str; 
} 

Zastosowanie: escaping tricky string to CSV format

+0

Po prostu próbowałem tego, działa natychmiast. Dziękuję Ci. –

+0

Nie potrzebujesz również ogólnych ograniczeń. Cieszę się, że znalazłeś to pomocne! – Romoku