Ce sujet est vraiment agréable pour moi. Dans de nombreuses applications Web, il est assez courant d'accepter les entrées utilisateur et de sauvegarder un seul enregistrement dans votre base de données. Mais qu'en est-il lorsque vos utilisateurs (ou vous) souhaitez effectuer plusieurs insertions en une seule commande?
Entrez cet article, qui expliquera comment créer un modèle CSV et un formulaire pour télécharger le fichier CSV, et comment analyser le fichier CSV dans un modèle Mongoose qui sera enregistré dans une base de données MongoDB..
Cet article suppose que vous avez une compréhension de base de Mongoose et de ses interactions avec MongoDB. Si vous ne le faites pas, je vous suggère de lire mon article Introduction à Mongoose pour MongoDB et Node.js en premier. Cet article décrit les interactions entre Mongoose et MongoDB en créant des schémas fortement typés à partir desquels un modèle est créé. Si vous avez déjà une bonne compréhension de Mongoose, alors poursuivons.
Pour commencer, instancions une nouvelle application Node.js. Dans une invite de commande, accédez à l'emplacement où vous souhaitez héberger vos applications Node.js et exécutez les commandes suivantes:
mkdir csvimport cd csvimport npm init
J'ai laissé toutes les valeurs par défaut en place, mon application va donc commencer par index.js
. Avant de créer et d’analyser des fichiers CSV, vous devez d’abord effectuer une première configuration. Je veux en faire une application Web; Pour ce faire, je vais utiliser le package Express afin de gérer l’ensemble de la configuration serveur nitty-gritty. Dans votre invite de commande, installez Express en exécutant la commande suivante:
npm install express --save
Étant donné que cette application Web acceptera les fichiers via un formulaire Web, je vais également utiliser le sous-package Express Express File Upload. Installons cela maintenant aussi:
npm installer express-fileupload --save
J'ai maintenant effectué suffisamment de configuration initiale pour configurer mon application Web et créer une page Web de base qui créera mon formulaire de téléchargement de fichier..
Voici mon index.js
fichier qui configure mon serveur web:
var app = require ('express') (); var fileUpload = require ('express-fileupload'); var server = require ('http'). Server (app); app.use (fileUpload ()); server.listen (80); app.get ('/', fonction (req, res) res.sendFile (__ dirname + '/index.html'););
Cet exemple importe les bibliothèques Express et Express File Upload, configure mon application Web pour utiliser le téléchargement de fichier et écoute sur le port 80. Cet exemple a également créé un itinéraire utilisant Express à "/", qui sera la page d'arrivée par défaut de mon site Web. application. Cet itinéraire renvoie un index.html
fichier contenant le formulaire Web qui permettra à un utilisateur de télécharger un fichier CSV. Dans mon cas, je cours sur mon ordinateur local. Ainsi, lors de ma visite à http: // localhost, je verrai le formulaire que je crée dans l'exemple suivant..
Voici mon index.html
page qui crée mon formulaire pour le téléchargement d'un fichier CSV:
Télécharger des auteurs Utilisez le formulaire ci-dessous pour télécharger une liste d'auteurs. Cliquez ici pour un exemple de modèle.
Ce fichier HTML contient deux choses importantes:
encType
définir comme multipart / form-data
et un champ de saisie avec un type de fichier
qui accepte les fichiers avec une extension "csv".Comme vous l'avez peut-être remarqué, le code HTML fait référence à un modèle d'auteur. Si vous lisez mon article Introduction to Mongoose, j'ai créé un schéma d'auteur. Dans cet article, je vais recréer ce schéma et permettre à l'utilisateur d'importer en bloc une collection d'auteurs dans ma base de données MongoDB. Jetons un coup d'oeil au schéma d'auteur. Avant de faire cela, cependant, vous l’avez probablement deviné: nous devons installer le paquet Mongoose:
npm install mongoose --save
Avec Mongoose installé, créons un nouveau author.js
fichier qui définira le schéma et le modèle de l'auteur:
var mangouste = require ('mangouste'); var authorSchema = mongoose.Schema (_id: mongoose.Schema.Types.ObjectId, nom: prénom: type: chaîne, obligatoire: true, nom: chaîne, biographie: chaîne, twitter: type: chaîne, valider : validator: function (text) if (text! == null && text.length> 0) renvoie text.indexOf ('https://twitter.com/') === 0; renvoie true;, message : "Le pseudo Twitter doit commencer par https://twitter.com/ ', facebook: type: Chaîne, valider: validateur: fonction (texte) if (text! == null && text.length> 0) return text.indexOf ('https://www.facebook.com/') === 0; return true;, message: 'La page Facebook doit commencer par https://www.facebook.com/', linkedin: type: String, validate: validator: function (text) if (text! == null && text.length> 0) renvoie text.indexOf ('https://www.linkedin.com/') = == 0; return true;, message: "LinkedIn doit commencer par https://www.linkedin.com/ ', profilePicture: Buffer, créé: type: Date, par défaut: Date.now); var Author = mongoose.model ('Auteur', authorSchema); module.exports = Auteur;
Avec le schéma et le modèle d'auteur créés, changeons de sujet et concentrons-nous sur la création du modèle CSV pouvant être téléchargé en cliquant sur le lien du modèle. Pour aider à la génération de modèles CSV, je vais utiliser le package JSON à CSV. Installons ça maintenant:
npm installer json2csv --save
Je vais maintenant mettre à jour mon précédent créé index.js
fichier pour inclure une nouvelle route pour "/ template":
var template = require ('./ template.js'); app.get ('/ template', template.get);
J'ai seulement inclus le nouveau code pour le modèle de route ajouté au précédent index.js
fichier.
La première chose que ce code fait est d’inclure un nouveau template.js
fichier (à créer ensuite) et créez un itinéraire pour "/ template". Cette route appellera un obtenir
fonctionner dans le template.js
fichier.
Avec le serveur Express mis à jour pour inclure le nouvel itinéraire, créons le nouveau template.js
fichier:
var json2csv = require ('json2csv'); exports.get = fonction (req, res) var champs = ['name.firstName', 'name.lastName', 'biographie', 'twitter', 'facebook', 'linkedin']; var csv = json2csv (data: ", fields: fields); res.set (" Content-Disposition "," pièce jointe; nomfichier = authors.csv "); res.set (" Content-Type "," application / octet-stream "); res.send (csv);;
Ce fichier comprend d’abord le fichier précédemment installé. json2csv
paquet. Je crée et exporte ensuite un obtenir
une fonction. Cette fonction accepte les objets requête et réponse du serveur Express..
Dans la fonction, j'ai créé un tableau des champs que je souhaite inclure dans mon modèle CSV. Cela peut être fait de deux manières. La première méthode (dans cet exemple) consiste à créer une liste statique des champs à inclure dans le modèle. La deuxième méthode consiste à créer de manière dynamique la liste des champs en extrayant les propriétés du schéma d’auteur..
La deuxième façon pourrait être faite avec le code suivant:
champs var = Object.keys (Author.schema.obj);
J'aurais aimé utiliser cette méthode dynamique, mais cela devient un peu compliqué lorsque je ne souhaite pas inclure plusieurs propriétés du schéma vers mon modèle CSV. Dans ce cas, mon modèle n'inclut pas le _id
et créé
propriétés car elles seront renseignées via le code. Toutefois, si vous ne souhaitez pas exclure de champs, la méthode dynamique fonctionnera également..
Avec le tableau de champs défini, j’utilise le json2csv
package pour créer mon modèle CSV à partir de mon objet JavaScript. Ce CSV
objet sera les résultats de cette route.
Et enfin, en utilisant le res
propriété du serveur Express, j’ai défini deux propriétés d’en-tête qui forceront le téléchargement d’un fichier. auteurs.csv
fichier.
À ce stade, si vous devez exécuter votre application Node et accéder à http: // localhost dans votre navigateur Web, le formulaire Web sera affiché avec un lien pour télécharger le modèle. En cliquant sur le lien pour télécharger le modèle, vous pourrez télécharger le auteurs.csv
fichier à remplir avant son téléchargement.
Voici un exemple de fichier CSV rempli:
name.firstName, name.lastName, biographie, twitter, facebook, linkedin Jamie, Munro, Jamie est développeur web et auteur ", Mike, Wilson, Mike est développeur web et auteur Node.js,,,
Cet exemple, une fois téléchargé, créera deux auteurs: moi-même et un ami qui a écrit un livre sur Node.js il y a quelques années. Vous remarquerez peut-être qu’à la fin de chaque ligne figurent trois virgules ",,". Ceci est fait pour abréger l'exemple. Je n'ai pas renseigné les propriétés du réseau social (gazouillement
, Facebook
, et linkedin
).
Les pièces du puzzle commencent à se rassembler et à former une image. Passons à la viande et aux pommes de terre de cet exemple et analysons ce fichier CSV. le index.js
Le fichier nécessite une mise à jour pour se connecter à MongoDB et créer un nouvel itinéraire POST qui acceptera le téléchargement du fichier:
var app = require ('express') (); var fileUpload = require ('express-fileupload'); var mangouste = require ('mangouste'); var server = require ('http'). Server (app); app.use (fileUpload ()); server.listen (80); mongoose.connect ('mongodb: // localhost / csvimport'); app.get ('/', fonction (req, res) res.sendFile (__ dirname + '/index.html');); var template = require ('./ template.js'); app.get ('/ template', template.get); var upload = require ('./ upload.js'); app.post ('/', upload.post);
Avec une connexion à la base de données et un nouvel itinéraire POST configurés, il est temps d'analyser le fichier CSV. Heureusement, il existe plusieurs grandes bibliothèques qui facilitent ce travail. J'ai choisi d'utiliser le fast-csv
package pouvant être installé avec la commande suivante:
npm installer fast-csv --save
La route POST a été créée de la même manière que la route modèle, qui appelle une poster
fonction de la upload.js
fichier. Il n'est pas nécessaire de placer ces fonctions dans des fichiers séparés; Cependant, j'aime créer des fichiers séparés pour ces routes, car cela aide à garder le code agréable et organisé..
Et enfin, créons le upload.js
fichier qui contient le poster
fonction appelée lorsque le formulaire créé précédemment est soumis:
var csv = require ('fast-csv'); var mangouste = require ('mangouste'); var Author = require ('./ author'); exports.post = function (req, res) if (! req.files) renvoie res.status (400) .send ('Aucun fichier n'a été téléchargé.'); var authorFile = req.files.file; var auteurs = []; csv .fromString (authorFile.data.toString (), en-têtes: true, ignoreEmpty: true) .on ("données", fonction (données) données ['_ id'] = new mongoose.Types.ObjectId (); authors.push (data);) .on ("end", function () Author.create (auteurs, function (err, documents) if (err) renvoie err;); res.send (authors.length + 'Les auteurs ont été téléchargés avec succès.');); ;
Un peu se passe dans ce fichier. Les trois premières lignes incluent les packages nécessaires pour analyser et sauvegarder les données CSV..
Ensuite, le poster
la fonction est définie et exportée pour être utilisée par le index.js
fichier. À l'intérieur de cette fonction est l'endroit où la magie a lieu.
La fonction vérifie d’abord qu’un fichier est contenu dans le corps de la demande. Si ce n'est pas le cas, une erreur est renvoyée, indiquant qu'un fichier doit être téléchargé..
Lorsqu'un fichier a été téléchargé, une référence au fichier est enregistrée dans une variable appelée authorFile
. Ceci est fait en accédant à la des dossiers
tableau et le fichier
propriété dans le tableau. le fichier
propriété correspond au nom de mon nom d'entrée de fichier que j'ai défini pour la première fois dans le index.html
Exemple.
J'ai aussi créé un auteurs
tableau qui sera rempli lorsque le fichier CSV sera analysé. Ce tableau sera utilisé pour sauvegarder les données dans la base de données.
le fast-csv
bibliothèque est maintenant appelée en tirant parti de la fromString
une fonction. Cette fonction accepte le fichier CSV en tant que chaîne. J'ai extrait la ficelle du authorFile.data
propriété. le Les données
propriété contient le contenu de mon fichier CSV téléchargé.
J'ai inclus deux options au fast-csv
une fonction: en-têtes
et ignorer le vide
. Ce sont tous deux mis à vrai
. Cela indique à la bibliothèque que la première ligne du fichier CSV contient les en-têtes et que les lignes vides doivent être ignorées..
Avec les options configurées, j’ai configuré deux fonctions d’écoute appelées lorsque le Les données
événement et le fin
événement sont déclenchés. le Les données
event est appelé une fois pour chaque ligne du fichier CSV. Cet événement contient un objet JavaScript des données analysées..
Je mets à jour cet objet pour inclure le _id
propriété de l'auteur Schema avec un nouveau ObjectId
. Cet objet est ensuite ajouté à la auteurs
tableau.
Lorsque le fichier CSV a été entièrement analysé, le fin
l'événement est déclenché. Dans la fonction de rappel d'événement, j'appelle le créer
fonction sur le modèle Author, en passant le tableau de auteurs
à cela.
Si une erreur survient lors de la tentative d’enregistrement du tableau, une exception est levée. sinon, un message de réussite s'affiche pour l'utilisateur, indiquant le nombre d'auteurs téléchargés et enregistrés dans la base de données..
Si vous souhaitez voir le code source complet, j'ai créé un référentiel GitHub avec le code.
Dans mon exemple, je n'ai téléchargé que quelques enregistrements. Si votre cas d'utilisation nécessite la possibilité de télécharger des milliers d'enregistrements, il peut être judicieux de les enregistrer en plusieurs morceaux..
Cela peut être fait de plusieurs manières. Si je devais le mettre en œuvre, je suggérerais de mettre à jour le Les données
fonction de rappel pour vérifier la longueur du tableau authors. Lorsque le tableau dépasse votre longueur définie, par exemple, 100, appelez le Auteur.créer
fonction sur le tableau, puis réinitialiser le tableau à vide. Cela permettra ensuite de sauvegarder les enregistrements par tranches de 100. Assurez-vous de laisser le dernier créer
appeler le fin
fonction de rappel pour sauvegarder les enregistrements finaux.
Prendre plaisir!