Manish Kumar
Manish Kumar

Reputation: 15497

Prompt a csv file to download as pop up using node.js and node-csv-parser (node module)

Recently I have started working with node.js. While going through a requirement in one of my projects I am facing an issue where I should be able to write some data to a csv file dynamically and let it prompt as a popup to download for user (with save and cancel options - as we normally see). After googling for some time I decided to use csv npm module https://github.com/wdavidw/node-csv-parser. I am able to write data into a file and save it using this module. I want to prompt a popup for saving this file with/without saving the file.

my code looks something like this:

    // Sample Data 
    var data = [["id", "subject1", "subject2", "subject3"], ["jack", 85, 90, 68], ["sam", 77, 89, 69]]

    // Server Side Code    
    var csv = require('../../node_modules/csv');            
    var fs = require('fs');

    createCSV = function(data, callback) {
        csv().from(data).to(fs.createWriteStream('D:/test.csv')) // writing to a file           
    }

    // Client side call sample
    $("#exportToCSV").click(function() {
        callToServer.createCSV(data);
       return false;
    });

This is working good as far as writing the csv file is concerned.

Any help is greatly appreciated. -Thanks

Upvotes: 14

Views: 41104

Answers (5)

joel.software
joel.software

Reputation: 1515

Manish Kumar's answer is spot on - just wanted to include a Express 4 syntax variant to accomplish this:

function(req, res) {
  var csv = GET_CSV_DATA // Not including for example.

  res.setHeader('Content-disposition', 'attachment; filename=testing.csv');
  res.set('Content-Type', 'text/csv');
  res.status(200).send(csv);

}

Upvotes: 36

Federico
Federico

Reputation: 6478

Express-csv is a great module for writing csv contents to stream from a node.js server, which will be sent as a response to the client (and downloaded as a file). Very easy to use.

app.get('/', function(req, res) {
  res.csv([
    ["a", "b", "c"]
  , ["d", "e", "f"]
  ]);
});

The docs: https://www.npmjs.com/package/express-csv

When you pass an object, you need to prepend the headers explicitly (if you want them). Here's my my example using npm mysql

router.route('/api/report')
    .get(function(req, res) {
            query = connection.query('select * from table where table_id=1;', function(err, rows, fields) {
                if (err) {
                    res.send(err);
                }
                var headers = {};
                for (key in rows[0]) {
                    headers[key] = key;
                }
                rows.unshift(headers);
                res.csv(rows);
            });
    });

Upvotes: 3

Palani
Palani

Reputation: 9042

Following solution is for Express

Express is evolved, instead of setting attachment and content type header, directly use attachment api http://expressjs.com/4x/api.html#res.attachment

Note: attachment() don't transfer the file, it just sets filename in header.

response.attachment('testing.csv');
csv().from(data).to(response);

Upvotes: 12

Manish Kumar
Manish Kumar

Reputation: 15497

I did it something like this :

http.createServer(function(request, response) {
    response.setHeader('Content-disposition', 'attachment; filename=testing.csv');
    response.writeHead(200, {
        'Content-Type': 'text/csv'
    });

    csv().from(data).to(response)

})
.listen(3000);

Upvotes: 15

Max
Max

Reputation: 8836

Check out this answer: Nodejs send file in response

Basically, you don't have to save the file to the hard drive. Instead, try sending it directly to the response. If you're using something like Express then it would look something like this:

var csv = require('csv');
req.get('/getCsv', function (req, res) {
    csv().from(req.body).to(res);
});

Upvotes: 0

Related Questions