Quelqu'un pourrait-il me dire pourquoi le code suivant ne fonctionne pas. Les données sont enregistrées dans le fichier csv, mais les données 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.
c#
csv
delimited-text
Darren Young
la source
la source
Réponses:
La version plus courte suivante s'ouvre correctement dans Excel, peut-être que votre problème était la virgule de fin
.net = 3,5
.net> = 4,0
Et comme Tim l'a souligné, si vous êtes sur .net> = 4, vous pouvez le rendre encore plus court:
Comme suggéré par Christian, si vous souhaitez gérer les caractères spéciaux s'échappant dans les champs, remplacez le bloc de boucle par:
Et dernière suggestion, vous pouvez écrire le contenu csv ligne par ligne plutôt que comme un document entier, pour éviter d'avoir un gros document en mémoire.
la source
ItemArray
dans un nouveauString[]
, vous pouvez l'omettre.ToArray()
avec .NET 4 et utiliser laString.Join
surcharge qui prend unIEnumerable<T>
(édité). 
est typique des documents HTML / XML. Ce n'est pas le code ci-dessus qui le produit à moins que le tableau ne contienne
explicitementJ'ai enveloppé cela dans une classe d'extension, qui vous permet d'appeler:
sur n'importe quel DataTable.
la source
Une nouvelle fonction d'extension basée sur la réponse de Paul Grimshaw. Je l'ai nettoyé et ajouté la possibilité de gérer des données inattendues. (Données vides, citations incorporées et virgules dans les en-têtes ...)
Il renvoie également une chaîne qui est plus flexible. Il renvoie Null si l'objet table ne contient aucune structure.
Vous l'appelez comme suit:
la source
Si votre code appelant fait référence à l'
System.Windows.Forms
assembly, vous pouvez envisager une approche radicalement différente. Ma stratégie consiste à utiliser les fonctions déjà fournies par le framework pour y parvenir en très peu de lignes de code et sans avoir à parcourir les colonnes et les lignes. Ce que fait le code ci-dessous est de créer par programme unDataGridView
à la volée et de définirDataGridView.DataSource
leDataTable
. Ensuite, je sélectionne par programme toutes les cellules (y compris l'en-tête) dansDataGridView
et appelleDataGridView.GetClipboardContent()
, plaçant les résultats dans WindowsClipboard
. Ensuite, je `` colle '' le contenu du presse-papiers dans un appel àFile.WriteAllText()
, en veillant à spécifier le formatage du `` coller '' commeTextDataFormat.CommaSeparatedValue
.Voici le code:
Remarquez que je m'assure également de conserver le contenu du presse-papiers avant de commencer, et de le restaurer une fois que j'ai terminé, afin que l'utilisateur n'obtienne pas un tas de déchets inattendus la prochaine fois que l'utilisateur essaie de coller. Les principales mises en garde à cette approche sont 1) Votre classe doit référencer
System.Windows.Forms
, ce qui peut ne pas être le cas dans une couche d'abstraction de données, 2) Votre assembly devra être ciblé pour le framework .NET 4.5, car DataGridView n'existe pas dans 4.0, et 3) La méthode échouera si le presse-papiers est utilisé par un autre processus.Quoi qu'il en soit, cette approche n'est peut-être pas adaptée à votre situation, mais elle n'en est pas moins intéressante et peut être un autre outil dans votre boîte à outils.
la source
.GetClipboardContent
gère également quelques cas extrêmes de valeurs contenant,
."
,\t
(il convertit tab en espace)Je l'ai fait récemment mais j'ai inclus des guillemets doubles autour de mes valeurs.
Par exemple, modifiez ces deux lignes:
la source
Essayez de changer
sb.Append(Environment.NewLine);
ensb.AppendLine();
.la source
Essayez de mettre
;
au lieu de,
J'espère que ça aide
la source
Lisez ceci et cela ?
Une meilleure mise en œuvre serait
la source
L'erreur est le séparateur de liste.
Au lieu d'écrire
sb.Append(something... + ',')
vous devriez mettre quelque chose commesb.Append(something... + System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator);
Vous devez placer le caractère séparateur de liste configuré dans votre système d'exploitation (comme dans l'exemple ci-dessus), ou le séparateur de liste dans la machine cliente où le fichier va être regardé. Une autre option serait de le configurer dans app.config ou web.config en tant que paramètre de votre application.
la source
4 lignes de code:
Notez que le
ToList()
à la fin est important; J'ai besoin de quelque chose pour forcer une évaluation d'expression. Si je codais le golf, je pourrais utiliser à laMin()
place.Notez également que le résultat aura une nouvelle ligne à la fin en raison du dernier appel à
AppendLine()
. Vous ne voudrez peut-être pas cela. Vous pouvez simplement appelerTrimEnd()
pour le supprimer.la source
Voici une amélioration de la publication de vc-74 qui gère les virgules de la même manière qu'Excel. Excel place des guillemets autour des données si les données comportent une virgule, mais ne les cite pas si les données ne comportent pas de virgule.
la source
Pour écrire dans un fichier, je pense que la méthode suivante est la plus efficace et la plus simple: (vous pouvez ajouter des guillemets si vous le souhaitez)
la source
Pour imiter Excel CSV:
la source
la source
la source
Le moyen le plus simple sera peut-être d'utiliser:
https://github.com/ukushu/DataExporter
en particulier dans le cas de vos données de datatable contenant des
/r/n
caractères ou un symbole de séparateur à l'intérieur de vos cellules dataTable.Presque toutes les autres réponses ne fonctionneront pas avec de telles cellules.il vous suffit d'écrire le code suivant:
la source
Au cas où quelqu'un d'autre trébucherait là-dessus, j'utilisais File.ReadAllText pour obtenir des données CSV, puis je les ai modifiées et écrites avec File.WriteAllText . Les CRLF \ r \ n fonctionnaient bien mais les onglets \ t étaient ignorés lorsque Excel l'ouvrait. (Toutes les solutions de ce fil jusqu'à présent utilisent un séparateur de virgule, mais cela n'a pas d'importance.) Le bloc-notes a montré le même format dans le fichier résultant que dans la source. Un Diff a même montré que les fichiers étaient identiques. Mais j'ai eu un indice lorsque j'ai ouvert le fichier dans Visual Studio avec un éditeur binaire. Le fichier source était Unicode mais la cible était ASCII . Pour corriger, j'ai modifié ReadAllText et WriteAllText avec le troisième argument défini comme System.Text.Encoding.Unicode , et à partir de là, Excel a pu ouvrir le fichier mis à jour.
la source
FYR
la source
Voici ma solution, basée sur les réponses précédentes de Paul Grimshaw et Anthony VO . J'ai soumis le code dans un projet C # sur Github .
Ma principale contribution est d'éliminer explicitement la création et la manipulation d'un
StringBuilder
et de travailler uniquement avecIEnumerable
. Cela évite l'allocation d'un gros tampon en mémoire.}
Cette approche se combine bien avec la conversion
IEnumerable
en DataTable comme demandé ici .la source
J'avais également besoin de faire un remplacement des données, c'est pourquoi il y a quelques déclarations «if else». Je devais m'assurer que si un champ était vide pour saisir "N / A" à la place, ou si un champ de date était formaté comme "01/01/1900: 00" qu'il serait enregistré comme "01/01/1900" au lieu.
la source
la source
si toutes les données sont toujours dans la première cellule, cela signifie que l'application avec laquelle vous avez ouvert le fichier attend un autre délimiteur. MSExcel peut gérer la virgule comme délimiteur, sauf indication contraire de votre part.
la source