7
votes

Utilisation de CSVHelper (Nuget) avec C # MVC pour importer des fichiers CSV

https://joshclose.github.io/csvhelper/ disponible via Nuget est utilisé pour Lire et écrire des fichiers CSV.

CSVHelper vous permet de lire votre fichier CSV directement dans votre classe personnalisée.

Comme suivant a été présenté dans un précédent question xxx blockQuote>

csvreader trouvera automatiquement Comment faire correspondre les noms de propriété Basé sur la ligne d'en-tête (c'est configurable). Il utilise compilé arbres d'expression au lieu de Réflexion, il est donc très rapide.

C'est aussi très extensible et configurable.

J'essaie essentiellement de déterminer comment lire dans un fichier CSV avec des en-têtes (noms inconnus) et lisez les enregistrements dans un objet personnalisé.

Il n'y a pas de documentation sur cette Du tout, si vous êtes demandé si quelqu'un savait comment utiliser CSVreader pour mettre les valeurs dans un tableau de chaînes ou comment recommanderiez-vous de traiter avec cela?


1 commentaires

Le site Web semble avoir déménagé à Joshclose.github.io/csvhelper


3 Réponses :


1
votes

Je sais que cela n'est pas lié aux CVShelpers, mais vous aimerez peut-être envisager le FichiersHelPers projet

Il vous permet de décorer des champs sur un objet avec des attributs de manière à ce qu'il représente une ligne dans le fichier CSV, puis utilisez un fichierHelperengine pour lire le fichier dans - résultant d'un tableau d'objets représentant une rangée

Voir ce Démarrage rapide sur la lecture de fichiers délimités


2 commentaires

Et si vous ne connaissez pas les noms d'en-tête et que vous ne savez pas que la quantité utilise-t-elle cela? Pouvez-vous l'obtenir pour analyser un tableau de cordes ou quelque chose de similaire? Comment cela fait-il gérer des caractères spéciaux et des cas de bord? Est-ce que ça va assez bien?


Je viens de trouver ceci:

Il y a un csvfieldattribute code> que vous pouvez mettre sur votre propriété où vous pouvez définir le nom du champ CSV ou l'index du champ CSV. Le nom ne fonctionnera que s'il y a une ligne d'en-tête dans le fichier CSV.

public class MyCustomClass
{
    [CsvField( FieldIndex = 1 )]
    public string Property1 { get; set; }

    [CsvField( FieldIndex = 0 )]
    public string Property2 { get; set; }

    [CsvField( FieldIndex = 2 )]
    public string Property3 { get; set; }
}


9 commentaires

Devrais-je utiliser CSVREADER pour saisir l'en-tête, puis CSVArser dans une boucle de While pour saisir les données de la ligne? Pourriez-vous fournir un exemple à cela?


Voir ma réponse ci-dessous. Est-ce le meilleur était de saisir toutes les données? L'étape suivante serait de permettre à l'utilisateur de faire correspondre des colonnes aux propriétés de mes entités. Je suis un peu inquiet de stocker l'ensemble du CSV entre les demandes cependant. Magasin de pensée en session ou en DB, mais les deux seront assez lourds (potentiellement)


Pour plus de détails, vous pouvez également faire référence à cette page wiki écrite par Josh Fermer (surprise!) github.com/joshcler/csvhelper/wiki/fluent-class-mapping


@JoshClose Hey Josh, je voulais juste mentionner que cette réponse était vraiment utile et merci pour le grand projet. Veuillez envisager de documenter Csvparser dans le wiki - je fais quelque chose d'étrange avec un format de CSV déchiqueté, et j'ai presque fini par utiliser un ancien projet de CSV non supporté de merde, car je n'ai pas pensé que le vôtre manipulait des scénarios non mappés jusqu'à ce que je ne soit arrivé sur cette réponse. :)


@Brianmackay Le lecteur a également divers autres méthodes si vous voulez le faire manuellement. I.e. t get (int columnindex)


@JoshClose Oui, j'ai vu que vous envisagez de couper les attributs de mappage en v2, non?


@BrianMackay Oui. Vous ne pouvez pas tout faire dans un attribut. La cartographie de référence est un bon exemple. C'est un désordre absolu d'avoir ce travail à travers des attributs. Les classes de cartographie ne sont que beaucoup plus flexibles et faciles à utiliser. Les fichiers seront toujours automobilisés si vous ne spécifiez pas de mappage, comme ils l'ont fait avec les attributs. Si vous avez des préoccupations ou des fonctionnalités, sentez-vous un message gratuit sur Google Group.


@JOSHCLOSE Merci Josh ... Fwiw, dans ma situation, il n'y a pas d'en-tête, je devais donc faire de la cartographie de l'index, et j'ai trouvé des attributs simples et propres. J'ai d'abord essayé la méthode fluide et elle n'a pas fonctionné instantanément. On sonne comme des attributs de cauchemarish dans des situations plus complexes. Merci encore. :)


@Brianmackay Oui, ça devient vraiment mauvais. La cartographie de classe ne fera que cartographier les propriétés que vous spécifiez spécifiquement et que les autres sont ignorées. Il y a une petite documentation à ce sujet (j'ai besoin d'ajouter beaucoup plus). GITUB.COM/JOSHCLOSE/CSVHELPER/WIKI/FLUENT-CLASS-MAPPAPTOFEDIEDO_/A >



9
votes

Ceci est ma première version, je vais mettre à jour en tant que je modifier les choses et la rendre plus complète, mais cela me donne toutes les données des tableaux de chaîne.

   [HttpPost]
        public ActionResult UploadFile(HttpPostedFileBase file)
        {

            ICsvParser csvParser = new CsvParser(new StreamReader(file.InputStream));
            CsvReader csvReader = new CsvReader(csvParser);
            string[] headers = {};
            List<string[]> rows = new List<string[]>();
            string[] row;
            while (csvReader.Read())
            {
                // Gets Headers if they exist
                if (csvReader.HasHeaderRecord && !headers.Any())
                {
                    headers = csvReader.FieldHeaders;
                }
                row = new string[headers.Count()];
                for (int j = 0; j < headers.Count(); j++)
                {
                    row[j] = csvReader.GetField(j);
                }
                rows.Add(row);
            }
            ImportViewModel model = new ImportViewModel(rows);
            return View(model);
        }


0 commentaires