web-dev-qa-db-fra.com

Écriture d'un fichier CSV en .net

J'ai une obligation d'exporter un ensemble de données en tant que fichier CSV.

J'ai passé un certain temps à chercher un ensemble de règles et j'ai réalisé qu'il y avait pas mal de règles et d'exceptions lors de l'écriture d'un fichier CSV.

http://knab.ws/blog/index.php?/archives/3-CSV-file-parser-and-writer-in-C-Part-1.htmlhttp : //bytes.com/topic/c-sharp/answers/236875-problems-streamwriter-output-csvhttp://social.msdn.Microsoft.com/forums/en-US/csharpgeneral/thread/0073fcbb-adab-40f0-b768-4bba803d3ccd

Alors maintenant, ce n'est pas un simple processus de séparation des chaînes avec des virgules, j'ai recherché un écrivain CSV existant soit tiers ou (espérons-le!) Inclus dans le framework .net.

Modifier: nouveau lien: http://www.thinqlinq.com/Post.aspx/Title/LINQ-to-CSV-using-DynamicObject-and-TextFieldParser

Le TextFieldParser est un objet VB (peut être référencé à partir de C #) qui analysera automatiquement les fichiers CSV. :)

Je me demandais si quelqu'un connaissait des bibliothèques .Net (2.0 -> 3.5 et 4.0) pratiques pouvant être utilisées pour générer un fichier CSV correctement formaté.

En outre, s'il existe des ensembles de règles pour générer des fichiers CSV.

Il y a beaucoup de détails sur les lecteurs CSV et l'analyse des fichiers CSV, mais pas autant sur l'écriture (ok, je sais que c'est juste le contraire: P).

http://www.codeproject.com/KB/database/CsvReader.aspx

Toute aide serait très appréciée :)

J'ai trouvé un autre article avec des règles CSV plus détaillées: http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm

Une bibliothèque tierce soignée est Linq-to-CSV (pas la bibliothèque de framework): http://www.codeproject.com/KB/linq/LINQtoCSV.aspx

Merci pour votre aide tout le monde. J'ai décidé que la meilleure solution serait de créer une classe statique simple qui fera le remplacement des caractères spéciaux (que Chris a mentionné).

Si j'avais besoin que Linq interroge mes fichiers CSV, je regarderais l'implémentation CodeProjects de Linq-to-CSV.

Merci encore :)

42
Russell

S'il y a des virgules dans votre cellule, entourez la cellule entière de guillemets doubles, par exemple:

cell 1,cell 2,"This is one cell, even with a comma",cell4,etc

Et si vous voulez une double citation littérale, faites-en deux, par exemple:

cell 1,cell 2,"This is my cell and it has ""quotes"" in it",cell 4,etc

Quant aux dates, respectez le format ISO, et ça devrait aller (par exemple aaaa-mm-jj hh: mm: ss)

21
Chris

CsvHelper (une bibliothèque que je gère) également disponible via NuGet.

CsvHelper peut automatiquement écrire vos objets de classe dans un fichier pour vous.

var myObj = new MyCustomClass
{
    Prop1 = "one",
    Prop2 = 2
};
var streamWriter = // Create a writer to somewhere...
var csvWriter = new CsvWriter( streamWriter );

// You can write a single record.
csvWriter.WriteRecord( myObj );

// You can also write a collection of records.
var myRecords = new List<MyCustomClass>{ myObj };
csvWriter.WriteRecords( myRecords );
48
Josh Close

Je voudrais juste ajouter qu'il y a un RFC qui spécifie le format CSV qui est ce que je considérerais comme la source canonique.

18
Richard Nienaber

J'ai beaucoup utilisé filehelpers et c'est assez génial pour générer des CSV.

6
lomaxx

Voici la fonction que vous pouvez utiliser pour générer une ligne de fichier CSV à partir de la liste de chaînes (IEnumerable (Of String) ou un tableau de chaînes peut également être utilisé):

Function CreateCSVRow(strArray As List(Of String)) As String
    Dim csvCols As New List(Of String)
    Dim csvValue As String
    Dim needQuotes As Boolean
    For i As Integer = 0 To strArray.Count() - 1
        csvValue = strArray(i)
        needQuotes = (csvValue.IndexOf(",", StringComparison.InvariantCulture) >= 0 _
                      OrElse csvValue.IndexOf("""", StringComparison.InvariantCulture) >= 0 _
                      OrElse csvValue.IndexOf(vbCrLf, StringComparison.InvariantCulture) >= 0)
        csvValue = csvValue.Replace("""", """""")
        csvCols.Add(If(needQuotes, """" & csvValue & """", csvValue))
    Next
    Return String.Join(",", csvCols.ToArray())
End Function

Comme je pense, il ne sera pas difficile de convertir de VB.NET en C #)

4
Evgeny Gorb

Je sais que vous avez dit que vous avez trouvé votre réponse, mais je voulais juste donner un vote pour la bibliothèque LINQtoCSV que vous avez mentionnée. Je l'ai utilisé dans quelques projets et cela fonctionne très bien pour garder votre code d'entreprise propre et ne pas se soucier des détails/particularités du format de fichier.

Peut-être que dans votre cas spécifique, il n'est pas trop difficile d'écrire l'exportateur, mais ce qui est bien avec cette bibliothèque, c'est qu'elle est bidirectionnelle. Si vous vous retrouvez à consommer le CSV sur la route, ce n'est pas beaucoup de code supplémentaire, et/ou cela vous donne une bibliothèque cohérente à utiliser sur de futurs projets.

3
super_seabass
3
TrueWill

Autre règle à ajouter aux autres: utilisez les virgules comme séparateurs de champ plutôt que comme terminateurs de champ. La raison en est qu'une virgule de fin à la fin d'une ligne peut être ambiguë: n'a-t-elle aucune signification ou signifie-t-elle une valeur NULL à la suite?

2
dan-gph

Vous pouvez utiliser ODBC pour lire et écrire des fichiers CSV (via OdbcConnection et une chaîne de connexion appropriée). Cela devrait être assez bon pour générer des fichiers CSV, et gérera des choses comme des citations pour vous; cependant je ont rencontré des problèmes lors de son utilisation pour lire des fichiers CSV générés par d'autres programmes.

2
itowlson

J'ai trouvé ce lien important qui est assez soigné. Je ne l'ai pas encore essayé, vous permettra de savoir comment ça se passe!

http://www.codeproject.com/KB/linq/LINQtoCSV.aspx

En y regardant de plus près, cette implémentation utilise essentiellement uniquement des règles de base:

caractères spéciaux =\n\"et le caractère séparateur.

s'il trouve des caractères spéciaux, entourez-les de guillemets. Remplacez le devis par un double guillemet.

Essentiellement les règles mentionnées par Chris. Je pense que la façon la plus simple de le faire est de créer ma méthode d'assistance en fonction des règles simples et de la réviser en fonction des besoins des utilisateurs.

0
Russell

Pouvez-vous utiliser un tableau de chaînes, puis concaténer en utilisant:

string out = "";
string[] elements = { "1", "2" };
foreach(string s in elements) { out += s + "," };
out = out.substring(0, out.Length-1);
0
user291066