2014-12-08 3 views
0

У меня есть контроллер MVC, который должен вернуть CSV-файл из string[][]. Я пробую этот пример:Сгенерировать CSV-файл из строки [] []

public FileContentResult DownloadCSV() 
{ 
    string[][] output = new string[][]{ 
      new string[]{"Col 1 Row 1", "Col 2 Row 1", "Col 3 Row 1"}, 
      new string[]{"Col1 Row 2", "Col2 Row 2", "Col3 Row 2"} 
     }; 
    return File(output, "text/csv", "Report123.csv"); 
} 

Но я не знаю, как создать файл. Как создать CSV-файл с string[][]?

+1

На какой части вы застряли? Открытие/создание файла? создавая список, разделенный запятыми? писать в файл? –

+0

В файле Return я не знаю, как создать файл. –

+0

Содержимое файла должно быть 'Byte []', а не 'string [] []'. Посмотрите, как преобразовать строку в массив байтов. –

ответ

1

Используйте метод расширения для генерации этого файлу

/// <summary> 
    /// Convert an array to string list, of the form "1,2,3,.."   
    /// </summary> 
    /// <param name="array">The array of numbers</param> 
    /// <returns>A string value</returns> 
    public static string ToCSVRow<T>(this T[] array) 
    { 
     string[] parts=new string[array.Length]; 
     for(int i=0; i<parts.Length; i++) 
     { 
      parts[i]=array[i].ToString(); 
     } 
     return string.Join(",", parts); 
    } 
    /// <summary> 
    /// Convert a jagged array to csv table, where each row has the form "1,2,3,.." 
    /// </summary> 
    /// <param name="array">The array of numbers</param> 
    /// <returns>A string value</returns> 
    public static string ToCSV<T>(this T[][] array) 
    { 
     List<string> csv=new List<string>(); 
     for(int i=0; i<array.Length; i++) 
     { 
      csv.Add(array[i].ToCSVRow()); 
     } 
     return string.Join(Environment.NewLine, csv.ToArray()); 
    } 

и использовать с

return File(output.ToCSV(), "text/csv", "Report123.csv"); 

Edit 1

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

/// <summary> 
    /// Convert an array to a csv row, of the form "1,2,3,4.." 
    /// </summary> 
    /// <typeparam name="T">The array type</typeparam> 
    /// <param name="list">The array</param> 
    /// <returns>A comma delimited string</returns> 
    public static string ToCSVRow<T>(this T[] list) 
    { 
     return string.Join(",", list); 
    } 

    /// <summary> 
    /// Convert a jagged array to csv table, where each row has the form "1,2,3,.." 
    /// </summary> 
    /// <param name="array">The array of numbers</param> 
    /// <returns>A string value</returns> 
    public static string ToCSV<T>(this T[][] array) 
    { 
     return string.Join(Environment.NewLine, array.Select((row) => string.Join(",", row))); 
    } 
+1

В качестве альтернативы вы можете использовать 'StringBulder' вместо' List ' – ja72

+0

. Количество повторений этих данных в этом примере меня огорчает. Вам действительно не нужен цикл for внутри метода ToCSVRow, поскольку метод 'string.Join' принимает' object [] '. 'string.Join' также принимает' IEnumerable 'и' IEnumerable ', поэтому вы можете просто передать ему простое выражение LINQ над' array' (изменить функцию ToCSV на 'return string.Join (Environment.NewLine, array .Select (ToolsEx.ToCSVRow)))), это обеспечит более чистый код, займет меньше времени для обработки и приведет к меньшему количеству итераций. –

2

Вот пример с использованием LINQ.

public FileContentResult DownloadCSV() 
{ 
    string[][] output = new string[][]{ 
     new string[]{"Col 1 Row 1", "Col 2 Row 1", "Col 3 Row 1"}, 
     new string[]{"Col1 Row 2", "Col2 Row 2", "Col3 Row 2"} 
    }; 

    var result = lines.Select(l=>string.Join(",", l)) 
         .Aggregate(new StringBuilder(), (sb, v) => sb.AppendLine(v)) 
         .ToString(); 

    return File(result, "text/csv", "Report123.csv"); 
} 

... как метод расширения ...

public static class ToolsEx 
{ 
    public static string ToCsvString(this string[][] lines) 
    { 
     var query = lines.Select(l=>string.Join(",", l)); 
     var result = query.Aggregate(new StringBuilder(), (sb, v) => sb.AppendLine(v)); 
     return result.ToString(); 
    } 
} 

... вспомнив, что string.Join использует StringBuilder Internal вы могли бы уменьшить это далее, чтобы быть просто (это может быть немного больше, если кто-то еще будет поддерживать это после вас) ...

public static string ToCsvString(this string[][] rows) 
{ 
    return string.Join(Environment.NewLine, rows.Select(row => string.Join(",", row))); 
} 
Смежные вопросы