How to import an Excel File with Nodejs? - node.js

I am a nodeJS programmer. I want to the import excel file into my mongoDB database table with validation.
Validation like if any field is blank then that record not inserted into database and after importing all data from the file display this record not inserted because that field is blank.
There are many package are available but i am confuse which one is better for import excel file.
So please help me which package to use to import an Excel file. And if a demo code is possible please answer it.

router.post('/transferFiles', function (req, res) {
var neatCsv = require('neat-csv');
var array;
var fs = require('fs');
var storage02 = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
cb(null, Date.now() + file.originalname);
}
});
var upload02 = multer({
storage: storage02
}).single('file');
console.log("req.file");
console.log(req.files);
upload02(req, res, function (err) {
if (err) {
console.log("upload error 1" + err);
}
//console.log(req.file);
/** Multer gives us file info in req.file object */
if (!req.file) {
console.log('No file Passed 1');
return;
}
fs.readFile(req.file.path, async function (err, result02) {
if (err) {
console.error(err);
return;
}
array = await neatCsv(result02);
});
here result02 is added in array.so easily you can data to mongodb with help of json

Related

Set filname by id generated by mongoose using multer node js

I am new in Node js API and I'm trying to upload an Image using multer + express + mongoose + postman
CODE:
var storage = multer.diskStorage({
destination: function (request, file, callback) {
callback(null, 'public/images/course');
},
filename: function (request, file, callback) {
return callback(null, file.originalname)
}
});
var upload = multer({storage : storage})
router.post('/course', upload.single('thumbnail'),async(req, res) => {
try{
var course = new Course({
name : req.body.name,
thumbnail : "placeholder" // set to path where file is uploaded
})
await course.save()
res.status(201).send(course)
}catch(e){
res.status(400).send(e)
}
})
I use postman to post request using form data and it creates an image with its originalFilename but i want the filename to be id generated by mongoose and i have seen somewhere that i can use filesystem for that but is there any way i can upload file after id is generated because when i do like this
var storage = multer.diskStorage({
destination: function (request, file, callback) {
callback(null, 'public/images/course');
},
filename: function (request, file, callback) {
if (request.data) {
console.log(file)
// TODO: consider adding file type extension
fileExtension = file.originalname.split('.')[1]
return callback(null, `${request.path}-${request.data._id.toString()}.${fileExtension}`);
}
// fallback to the original name if you don't have a book attached to the request yet.
return callback(null, file.originalname)
}
});
var upload = multer({storage : storage}).single('thumbnail')
router.post('/course',(req, res) => {
console.log(req.body)
const course = new Course({
name : req.body.name,
thumbnail : req.body.name
})
//console.log(course)
req.data = course
//console.log(req.file)
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
// A Multer error occurred when uploading.
} else if (err) {
// An unknown error occurred when uploading.
}
// Everything went fine.
})
})
Then i got request body empty.
Thanks in advance

Get value from function then make it global

How can I get the value from inside the function to use it when posting data to database? Here I want to make the value of imageName inside the multer.diskStorage to be global so I can use it when posting the path to database
var imageName;
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/assets/images');
},
filename: function (req, file, cb) {
if (!file.originalname.match(/\.(png|jpg|jpeg)$/)) {
var err = new Error();
err.code = 'filetype';
return cb(err);
} else {
imageName = Date.now() + '_' + file.originalname;
cb(null, imageName);
}
}
});
router.post('/newsfeeds', parser.single("myfile"), function (req, res) {
newsfeed.path = imageName;
newsfeed.save(function (err) {
});
});
This is a way to implement multer. You can use upload as a function or as a middleware, I use it as a function because it allows me a more detailed handling of errors.
It was not necessary a global variable, in this case at the moment that multer processes the image fills the req.file property with the information of the image, as we overwrite the function filename now in req.file.filename this is the custom value that we need.
const multer = require('multer');
const multerStorage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/assets/images');
},
filename: function (req, file, cb) {
if (!file.originalname.match(/\.(png|jpg|jpeg)$/)) {
var err = new Error();
err.code = 'filetype';
return cb(err);
} else {
const imageName = Date.now() + '_' + file.originalname;
cb(null, imageName);
}
}
});
const upload = multer({ storage: multerStorage }).single('myfile');
router.post('/newsfeeds',(req, res) => {
upload(req, res, function (err) {
if (err || !req.file) {
// An error occurred while loading the image.
return res.status(400);
}
newsfeed.path = req.file.filename;
newsfeed.save(function (err) {
});
});
});
Here you can find a table with the rest of the properties of the image
that you have after multer processes the image. Documentation
Global variables tend to be frowned upon in the programming community, so you should first ask yourself if it's really what you want to do.
If you do decide it's the best approach, though, in Node you can attach a property to the global variable. In the browser, you can attach it to window.
As for your issue with the order of execution (from the OP's comments), you can add a Promise instead of a value to the global scope. Then, anytime you want that value, call .then() on your value, or run it in an async function with await.

Multer array returns only one file

I'm using multer to store multiple files in the database.
The files are stored properly in my DB, however, if I print req.files I only get just one file.
This is my code:
var storage = GridfsStorage({
url: config.mongo.uri,
filename(req, file, cb) {
cb(null, file.originalname);
},
metadata(req, file, cb) {
cb(null, {owner: req.params.driver})
}
});
var upload = multer({ storage: storage }).array('files[]');
return upload(req, res, function (err) {
if(err) {
handleError(err);
}
console.log(req.files); // --> Getting only one file, even thought it stores all of them
respondWithResult(req.files, 201);
})
Thanks for helping!

Cannot retrieve body text along with upload, Express js

I have a form that asks for a text and a file. I use multer for the file upload. The problem is I cannot retrieve the text with req.body if i use enctype=multipart/form-data
Route file
router.post('/new-job', function(req,res,next){
upload(req,res,function(err) {
if(err) {
return res.end("Error uploading file.");
}
});
var newJob = {
job_name: req.body.job_name, //Cannot retrieve this two
job_desc: req.body.job_desc,
};
var newJobData = new Jobs(newJob);
newJobData.save(function(err,user){
if(err)
console.log(err);
});
res.render('jobs/new-job', {job_added:true});
});
Multer configs
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, 'public/uploads');
},
filename: function (req, file, callback) {
callback(null, file.originalname);
}
});
Notes
I used method post
If i log the req.body.job_name it returns an undefined
If i remove the enctype=multipart/form-data i can retrieve the text just fine, though i cannot upload the file
You cannot access req.body contents until you're parsed the request, so either move your code inside your upload() callback, or get rid of the explicit upload() call entirely and just put upload before your route handler:
router.post('/new-job', upload, function(req, res, next) {
var newJob = {
// ...

Rename a file with multer is not working

I'm trying to rename a file using multer. I want to rename the file uploaded to a .jpg
Instead of the tutorial about multer, i'm calling the method rename in my route file. The file is well uploaded but I don't get why the function rename is not working.
By the way, the word 'ici' doesn't appear into my console
router.post('/edit/saveEdit',multer({
rename : function(fieldname, filename, req, res) {
console.log('ici');
return req.body.infoUser.id
}}),
function(req,res){
// console.log(req.body);
// console.log(JSON.stringify(req.files));
var conf = JSON.parse(fs.readFileSync(file_user));
var user = req.body.infoUser;
//changement de nom de fichier
// console.log(req.files.uploadAvatar);
Thanks for answers/help
Thibault
res.end('good');
It is working for me with the code as below:
var multer = require('multer')
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/uploads/')
},
filename: function (req, file, cb) {
var getFileExt = function(fileName){
var fileExt = fileName.split(".");
if( fileExt.length === 1 || ( fileExt[0] === "" && fileExt.length === 2 ) ) {
return "";
}
return fileExt.pop();
}
cb(null, Date.now() + '.' + getFileExt(file.originalname))
}
})
var multerUpload = multer({ storage: storage })
var uploadFile = multerUpload.single('file');
try using multer first for performing the desired operation on file and then serving the request.
example :
router.use(multer({
dest: './path/to/folder',
rename : function (fieldname, filename, req, res) {
console.log('ici');
return req.body.infoUser.id
}
}
)));
router.post('/edit/saveEdit', function(req, res){
// Operations saveEdit is hit
});
It is working on my side, please check if that works for you as well.
app.post('/api/photo', function(req, res) {
upload(req,res,function(err) {
if(err) {
return res.end("Error uploading file.");
}
//console.log("Resopnse "+res); e74e107b91f6ed71c70eabb2c2d87d6c
res.end("File is uploaded .... "+Date.now());
});
});

Resources