Search code examples
node.jscsvexpressexport-to-csv

Node.JS + Express parse CSV file on server


Essentially, what I have is a form where a user will upload a CSV file.

<form action="/upload" method="POST" enctype="multipart/form-data">
    <div class="custom-file">
        <input type="file" class="custom-file-input" id="customFile" name="file" required>
        <label class="custom-file-label" for="customFile">Choose file</label>
    </div>
    <input type="submit" class="btn btn-primary btn-block">
</form>

FYI: I'm using getbootstrap.com as my style sheet.

Now, the form sends a POST request to /upload which is where my node.js code is. What I need is for the server to parse this CSV file and extract the data. I've got no idea what to do as all the different NPM packages such as Multer are using a system where the save the file locally and then parse it.

Edit: Forgot to mention this, but temporary local CSV hosting is not an option. I need the client to upload server to process it and push to a DB, can't save the file locally anywhere.

Edit 2: I've used multer and the memory processing option and have gotten the following.

const express = require("express");
const app = express();
var bodyParser = require("body-parser");
var multer  = require('multer');
var storage = multer.memoryStorage();
var upload = multer({ storage: storage });
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static("public"));

app.get("/", function(req, res) {
  response.sendFile(__dirname + "/views/index.html");
});
app.post("/upload", upload.single('file'), async (req, res) => {    
  res.send(req.file)
});
const listener = app.listen(process.env.PORT, function() {
  console.log("Your app is listening on port " + listener.address().port);
});

Now once I upload the file, I'm getting the following response (this is what req.file is).

{"fieldname":"file","originalname":"tech.csv","encoding":"7bit","mimetype":"application/octet-stream","buffer":{"type":"Buffer","data":[67,76,65,83,83,32,73,68,44,84,69,67,72,32,35,44,70,73,82,83,84,32,78,65,77,69,44,76,65,83,84,32,78,65,77,69,13,10,54,79,44,54,79,48,49,44,65,110,105,115,104,44,65,110,110,101]},"size":56}

So It's pretty clear that our data happens to be

67,76,65,83,83,32,73,68,44,84,69,67,72,32,35,44,70,73,82,83,84,32,78,65,77,69,44,76,65,83,84,32,78,65,77,69,13,10,54,79,44,54,79,48,49,44,65,110,105,115,104,44,65,110,110,101

but how do I process that? The csv file data was

CLASS ID,TECH #,FIRST NAME,LAST NAME
6O,6O01,Anish,Anne

So how do I go from the information provided in the buffer data attribute to the actual data?


Solution

  • All you have to use is Multer. Multer will return a buffer object which you can then make a string with the .toString() attribute.

    Code:

    const express = require("express");
    const app = express();
    var bodyParser = require("body-parser");
    var multer  = require('multer');
    var storage = multer.memoryStorage();
    var upload = multer({ storage: storage });
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(bodyParser.json());
    app.use(express.static("public"));
    
    app.get("/", function(request, response) {
      response.sendFile(__dirname + "/views/index.html");
    });
    
    app.post("/upload", upload.single('file'), async (req, res) => {    
      var b = req.file["buffer"]
      console.log(b.toString())
      res.send(b.toString())
    });
    
    const listener = app.listen(process.env.PORT, function() {
      console.log("Your app is listening on port " + listener.address().port);
    });