Este tópico é muito agradável para mim. É bastante comum em muitos aplicativos da Web aceitar a entrada do usuário e salvar um único registro em seu banco de dados. Mas e quando seus usuários (ou você) desejam realizar várias inserções em um único comando?
Neste artigo, demonstraremos como criar um modelo CSV e um formulário para fazer upload do arquivo CSV e como analisar o CSV em um modelo Mongoose que será salvo em um banco de dados MongoDB.
Este artigo pressupõe que você tenha um entendimento básico do Mongoose e como ele interage com o MongoDB. Se não, sugiro que leia meu Introdução ao Mongoose para MongoDB e Node.js artigo primeiro. Este artigo descreve como o Mongoose interage com o MongoDB criando esquemas fortemente tipados a partir dos quais um modelo é criado. Se você já tem um bom entendimento do Mongoose, então vamos prosseguir.
Começando
Para começar, você instanciaria um novo aplicativo Node.js. Em um prompt de comando, navegue até onde deseja hospedar seus aplicativos Node.js e execute os seguintes comandos:
mkdir csvimport cd csvimport npm init -y
Usando o -y
sinalizador, o projeto é inicializado com os valores padrão em vigor, então o aplicativo começará com index.js. Antes de criar e analisar arquivos CSV, algumas configurações iniciais precisam ser feitas primeiro. Queremos fazer disso uma aplicação web; para fazer isso, você usará o pacote Express para lidar com todas as configurações básicas do servidor. No prompt de comando, instale o Express executando o seguinte comando:
npm install express --save
Como este aplicativo da web aceitará arquivos por meio de um formulário da web, também usaremos o subpacote Express Express File Upload. Vamos instalar isso agora também:
npm install express-fileupload --save
Fizemos configuração inicial suficiente para configurar o aplicativo da web e criar uma página da web básica que criará um formulário de upload de arquivo.
No diretório raiz, crie um index.js arquivo e adicione os seguintes trechos de código. Este arquivo configura o servidor web.
var app = require('express')(); var fileUpload = require('express-fileupload'); var server = require('http').Server(app); app.use(fileUpload()); app.get('/', function (req, res) { res.sendFile(__dirname + '/index.html'); }); server.listen(8080, () => { console.log('Server started on port 8080') })
Este arquivo importa as bibliotecas Express e Express File Upload, configura o aplicativo web para usar o File Upload e escuta na porta 8080. Ele também cria uma rota usando Express em “/” que será a página inicial padrão para o aplicativo web. Esta rota retorna um index.html arquivo que contém o formulário da web que permitirá que um usuário carregue um arquivo CSV.
Você pode iniciar seu servidor web executando o comando em seu terminal:
node index.js
Você deve receber a mensagem no seu terminal Servidor iniciado na porta 8080. Isso significa que você se conectou com sucesso ao servidor web.
No diretório raiz, crie um index.html Arquivo. Este arquivo cria o formulário para carregar um arquivo CSV.
Upload Authors Use the form below to upload a list of authors. Click here for an example template.
Este arquivo HTML contém duas coisas importantes:
- Um link para /modelo que, ao ser clicado, fará o download de um modelo CSV que poderá ser preenchido com as informações a serem importadas.
- Um formulário com o
encType
definir comomultipart/form-data
e um campo de entrada com um tipo defile
que aceita arquivos com .csv extensão. omultipart/form-data
é um método de codificação usado em HTML quando o formulário contém um upload de arquivo.
Quando você visita http://localhost:8080/ você verá o formulário criado anteriormente.
Como você deve ter notado, o HTML faz referência a um modelo de autor. Se você ler o Introdução ao Mangusto artigo, foi criado um Esquema de Autor. Neste artigo, você recriará esse esquema e permitirá que o usuário importe em massa uma coleção de autores para o banco de dados MongoDB. Vamos dar uma olhada no Esquema do Autor. Antes de fazermos isso, porém, você provavelmente adivinhou – precisamos instalar o pacote Mongoose:
npm install mongoose --save
Criando o esquema e o modelo
Com o Mongoose instalado, vamos criar um novo autor.js arquivo que definirá o esquema e o modelo do autor:
var mongoose = require('mongoose'); var authorSchema = mongoose.Schema({ _id: mongoose.Schema.Types.ObjectId, name: { firstName: { type: String, required: true }, lastName: String }, biography: String, twitter: { type: String, validate: { validator: function(text) { if (text !== null && text.length > 0) return text.indexOf('https://twitter.com/') === 0; return true; }, message: 'Twitter handle must start with https://twitter.com/' } }, facebook: { type: String, validate: { validator: function(text) { if (text !== null && text.length > 0) return text.indexOf('https://www.facebook.com/') === 0; return true; }, message: 'Facebook Page must start with https://www.facebook.com/' } }, linkedin: { type: String, validate: { validator: function(text) { if (text !== null && text.length > 0) return text.indexOf('https://www.linkedin.com/') === 0; return true; }, message: 'LinkedIn must start with https://www.linkedin.com/' } }, profilePicture: Buffer, created: { type: Date, default: Date.now } }); var Author = mongoose.model('Author', authorSchema); module.exports = Author;
Com o esquema e o modelo do autor criados, vamos mudar de assunto e focar na criação do modelo CSV que pode ser baixado clicando no link do modelo. Para ajudar na geração do modelo CSV, usaremos o json2csv pacote. Este pacote npm cconverte JSON em CSV com títulos de coluna e finais de linha adequados.
npm install json2csv --save
Agora você vai atualizar o criado anteriormente index.js arquivo para incluir uma nova rota para /modelo. Você anexará este novo código para a rota do modelo ao arquivo criado anteriormente index.js Arquivo
var template = require('./template.js'); app.get("https://code.tutsplus.com/template", template.get);
A primeira coisa que este código faz é incluir um novo template.js arquivo (a ser criado em seguida) e crie uma rota para /modelo. Esta rota chamará um get
função no template.js Arquivo.
Com o servidor Express atualizado para incluir a nova rota, vamos criar o novo template.js Arquivo:
var json2csv = require('json2csv').parse; exports.get = function(req, res) { var fields = [ 'name.firstName', 'name.lastName', 'biography', 'twitter', 'facebook', 'linkedin' ]; var csv = json2csv({ data: '', fields: fields }); res.set("Content-Disposition", "attachment;filename=authors.csv"); res.set("Content-Type", "application/octet-stream"); res.send(csv); };
Este arquivo inclui primeiro o instalado json2csv
pacote. Em seguida, ele cria e exporta um get
função. Esta função aceita os objetos de solicitação e resposta do servidor Express.
Dentro da função, você cria uma matriz dos campos que deseja incluir no modelo CSV. Isso pode ser feito de duas maneiras. A primeira maneira (que é feita neste tutorial) é criar uma lista estática dos campos a serem incluídos no modelo. A segunda maneira é criar dinamicamente a lista de campos extraindo as propriedades do esquema do autor.
A segunda maneira poderia ser feita com o seguinte código:
var fields = Object.keys(Author.schema.obj);
Teria sido uma boa ideia usar o método dinâmico, mas se torna um pouco complicado quando você não deseja incluir várias propriedades do Schema para o modelo CSV. Nesse caso, nosso modelo CSV não inclui o _id
e created
properties porque estes serão preenchidos via código. No entanto, se você não tiver campos que deseja excluir, o método dinâmico também funcionará.
Criando o modelo CSV
Com o array de campos definido, você usará o json2csv
pacote para criar o modelo CSV do seu objeto JavaScript. este csv
objeto serão os resultados desta rota.
E por fim, usando o res
propriedade do servidor Express, serão definidas duas propriedades de cabeçalho que forçarão o download de um autores.csv Arquivo.
Neste ponto, se você executar seu aplicativo Node e navegar para http://localhost:8080/ em seu navegador da web, o formulário da web seria exibido com um link para baixar o modelo. Clicar no link para baixar o modelo permitirá que você baixe o autores.csv Arquivo. Este arquivo será preenchido antes de ser carregado.
Abrindo o arquivo de modelo no Microsoft Excel, o arquivo CSV deve ser preenchido da seguinte forma:
Aqui está um exemplo do arquivo CSV preenchido
name.firstName,name.lastName,biography,twitter,facebook,linkedin Mary,Doe,frontend developer,https://twitter.com/mary,https://www.facebook.com/mary,https://www.linkedin.com/mary Michael,Doe,backend developer,https://twitter.com/michael,https://www.facebook.com/michael,https://www.linkedin.com/michael John,Doe,app developer,https://twitter.com/john,https://www.facebook.com/john,https://www.linkedin.com/john
Este exemplo, quando carregado, criará três autores.
As peças do quebra-cabeça estão começando a se juntar e formar uma imagem. Vamos para a carne e as batatas deste exemplo e analisar esse arquivo CSV. o index.js O arquivo requer alguma atualização para se conectar ao MongoDB e criar uma nova rota POST que aceitará o upload do arquivo:
var app = require('express')(); var fileUpload = require('express-fileupload'); var server = require('http').Server(app); var template = require('./template.js'); var upload = require('./upload.js'); app.use(fileUpload()); app.get('/', function (req, res) { res.sendFile(__dirname + '/index.html'); }); app.get("https://code.tutsplus.com/template", template.get); app.post('/', upload.post); mongoose.connect('mongodb://localhost/csvimport'); server.listen(8080, () => { console.log('Server started on port 8080') })
Com uma conexão de banco de dados e uma nova rota POST configurada, é hora de analisar o arquivo CSV. Felizmente, existem várias bibliotecas excelentes que ajudam nesse trabalho. Para este tutorial, usaremos o fast-csv
pacote que pode ser instalado com o seguinte comando:
npm install fast-csv --save
A rota POST foi criada de forma semelhante à rota modelo que invoca um post
função do upload.js Arquivo. Não é necessário colocar essas funções em arquivos separados; no entanto, é melhor criar arquivos separados para essas rotas, pois isso ajuda a manter o código organizado e organizado.
Enviando dados
E, finalmente, vamos criar o upload.js arquivo que contém o post
função que é chamada quando o formulário criado anteriormente é enviado:
var csv = require('fast-csv'); var mongoose = require('mongoose'); var Author = require('./author'); exports.post = function (req, res) { if (!req.files) return res.status(400).send('No files were uploaded.'); var authorFile = req.files.file; var authors = []; csv .fromString(authorFile.data.toString(), { headers: true, ignoreEmpty: true }) .on("data", function(data){ data['_id'] = new mongoose.Types.ObjectId(); authors.push(data); }) .on("end", function(){ Author.create(authors, function(err, documents) { if (err) throw err; }); res.send(authors.length + ' authors have been successfully uploaded.'); }); };
Um pouco está acontecendo neste arquivo. As três primeiras linhas incluem os pacotes necessários que serão necessários para analisar e salvar os dados CSV.
A seguir, o post
função é definida e exportada para uso pelo index.js Arquivo. Dentro desta função é onde a mágica acontece.
A função primeiro verifica se há um arquivo contido no corpo da solicitação. Se não houver, um erro será retornado indicando que um arquivo deve ser carregado.
Quando um arquivo é carregado, uma referência ao arquivo é salva em uma variável chamada authorFile
. Isso é feito acessando o files
matriz e o file
propriedade na matriz. o file
propriedade corresponde ao nome do meu nome de entrada de arquivo que foi definido pela primeira vez no index.html exemplo.
Um vazio authors
A matriz que será preenchida à medida que o arquivo CSV é analisado é criada. Esta matriz será usada para salvar os dados no banco de dados.
o fast-csv
biblioteca agora é chamada aproveitando o fromString
função. Esta função aceita o arquivo CSV como uma string. A string é extraída do authorFile.data
propriedade. o data
A propriedade contém o conteúdo do arquivo CSV carregado.
A próxima linha inclui duas opções para o fast-csv
função: headers
e ignoreEmpty
. Ambos estão configurados para true
. Isso informa à biblioteca que a primeira linha do arquivo CSV conterá os cabeçalhos e que as linhas vazias devem ser ignoradas.
Com as opções configuradas, configuramos duas funções de listener que são chamadas quando o data
evento e o end
evento são acionados. o data
O evento é chamado uma vez para cada linha do arquivo CSV. Este evento contém um objeto JavaScript dos dados analisados.
O objeto é atualizado para incluir o _id
propriedade do esquema do autor com um novo ObjectId
. Este objeto é então adicionado ao authors
variedade.
Quando o arquivo CSV tiver sido totalmente analisado, o end
evento é acionado. Dentro da função callback do evento, chamaremos o create
função no modelo de autor, passando a matriz de authors
para isso.
Se ocorrer um erro ao tentar salvar a matriz, uma exceção será lançada; caso contrário, uma mensagem de sucesso é exibida ao usuário indicando quantos autores foram carregados e salvos no banco de dados.
O esquema do banco de dados deve ser semelhante a este:
Se você quiser ver o código-fonte completo, confira o repositório do GitHub com o código.
Conclusão
Neste tutorial, carregamos apenas alguns registros. Se o seu caso de uso exigir a capacidade de fazer upload de milhares de registros, pode ser uma boa ideia salvar os registros em partes menores.
Isso pode ser feito de várias maneiras. Se eu fosse implementá-lo, sugiro atualizar o data
função de retorno de chamada para verificar o comprimento da matriz de autores. Quando a matriz excede seu comprimento definido, por exemplo, 100, chame o Author.create
função na matriz e, em seguida, redefina a matriz para vazio. Isto irá salvar os registros em pedaços de 100. Certifique-se de deixar o final create
ligue no end
função de retorno de chamada para salvar os registros finais.
Apreciar!
Este post foi atualizado com contribuições de Mary Okosun. Mary é desenvolvedora de software com sede em Lagos, Nigéria, com experiência em tecnologias Node.js, JavaScript, MySQL e NoSQL.
Miniatura de postagem gerada com OpenAI DALL-E.