128 votes

c # datatable to csv

Quelqu'un pourrait-il me dire pourquoi le code suivant ne fonctionne pas? Les données sont enregistrées dans le fichier csv, mais elles ne sont pas séparées. Tout existe dans la première cellule de chaque ligne.

 StringBuilder sb = new StringBuilder();

foreach (DataColumn col in dt.Columns)
{
    sb.Append(col.ColumnName + ',');
}

sb.Remove(sb.Length - 1, 1);
sb.Append(Environment.NewLine);

foreach (DataRow row in dt.Rows)
{
    for (int i = 0; i < dt.Columns.Count; i++)
    {
        sb.Append(row[i].ToString() + ",");
    }

    sb.Append(Environment.NewLine);
}

File.WriteAllText("test.csv", sb.ToString());
 

Merci.

247voto

vc 74 Points 15694

Le suivant version plus courte s'ouvre bien dans Excel, peut-être que votre problème a été la virgule

.net <= 3.5

StringBuilder sb = new StringBuilder(); 

string[] columnNames = dt.Columns.Cast<DataColumn>().
                                  Select(column => column.ColumnName).
                                  ToArray();
sb.AppendLine(string.Join(",", columnNames));

foreach (DataRow row in dt.Rows)
{
    string[] fields = row.ItemArray.Select(field => field.ToString()).
                                    ToArray();
    sb.AppendLine(string.Join(",", fields));
}

File.WriteAllText("test.csv", sb.ToString());

.net >= 4.0

Et comme Tim l'a souligné, si vous êtes sur .net>=4, vous pouvez la rendre encore plus courte:

StringBuilder sb = new StringBuilder(); 

IEnumerable<string> columnNames = dt.Columns.Cast<DataColumn>().
                                  Select(column => column.ColumnName);
sb.AppendLine(string.Join(",", columnNames));

foreach (DataRow row in dt.Rows)
{
    IEnumerable<string> fields = row.ItemArray.Select(field => field.ToString());
    sb.AppendLine(string.Join(",", fields));
}

File.WriteAllText("test.csv", sb.ToString());

Comme suggéré par Christian, si vous voulez gérer les caractères spéciaux s'échapper dans les champs, remplacer la boucle par bloc:

foreach (DataRow row in dt.Rows)
{
    IEnumerable<string> fields = row.ItemArray.Select(field => 
      string.Concat("\"", field.ToString().Replace("\"", "\"\""), "\""));
    sb.AppendLine(string.Join(",", fields));
}

Et dernière suggestion, vous pouvez écrire le contenu csv ligne par ligne au lieu de l'ensemble du document, pour éviter d'avoir un gros document en mémoire.

45voto

Paul Grimshaw Points 3004

Je l'ai encapsulé dans une classe d'extension, qui vous permet d'appeler:

 myDataTable.WriteToCsvFile("C:\\MyDataTable.csv");
 

sur n'importe quel DataTable.

 public static class DataTableExtensions {
        public static void WriteToCsvFile(this DataTable dataTable, string filePath) {
            StringBuilder fileContent = new StringBuilder();

            foreach (var col in dataTable.Columns) {
                fileContent.Append(col.ToString() + ",");
            }

            fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);



            foreach (DataRow dr in dataTable.Rows) {

                foreach (var column in dr.ItemArray) {
                    fileContent.Append("\"" + column.ToString() + "\",");
                }

                fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);
            }

            System.IO.File.WriteAllText(filePath, fileContent.ToString());

        }
    }
}
 

7voto

Ben Jakuben Points 2049

Je l'ai fait récemment, mais j'ai inclus des guillemets doubles autour de mes valeurs.

Par exemple, modifiez ces deux lignes:

 sb.Append("\"" + col.ColumnName + "\","); 
...
sb.Append("\"" + row[i].ToString() + "\","); 
 

7voto

Neil Knight Points 23759

Essayez de changer sb.Append(Environment.NewLine); en sb.AppendLine(); .

 StringBuilder sb = new StringBuilder();          
foreach (DataColumn col in dt.Columns)         
{             
    sb.Append(col.ColumnName + ',');         
}          

sb.Remove(sb.Length - 1, 1);         
sb.AppendLine();          

foreach (DataRow row in dt.Rows)         
{             
    for (int i = 0; i < dt.Columns.Count; i++)             
    {                 
        sb.Append(row[i].ToString() + ",");             
    }              

    sb.AppendLine();         
}          

File.WriteAllText("test.csv", sb.ToString());
 

5voto

alexl Points 4535

Essayez de mettre ; au lieu de ,

J'espère que ça aide

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X