Skip to content

Instantly share code, notes, and snippets.

@killercup
Last active June 10, 2021 22:02
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save killercup/11256050 to your computer and use it in GitHub Desktop.
Save killercup/11256050 to your computer and use it in GitHub Desktop.
Streamed CSV Export using node-restify and mongoose
/**
* # Some Demo API Service
*/
var restify = require('restify');
var map = require('map-stream');
var csvify = require('../helpers/csvify');
var Team = require("../models").Team;
module.exports = {
/**
* ## CSV Export
*/
csvExport: function (req, res, next) {
res.writeHead(200, {
'Content-Type': 'text/csv',
'Content-Disposition': 'attachment; filename=export.csv'
});
res.write(csvify.rowFromArray(Team.csvHeader()));
Team
.find({accepted: true})
.populate({path: '_users'})
.stream()
.pipe(map(function teamToArray (team, callback) {
callback(null, team.mapToCSV());
}))
.pipe(map(function myCSVify (data, callback) {
callback(null, csvify.rowFromArray(data));
}))
.on('error', function csvError (err) {
console.log("oh noes, csv error!", err.stack);
})
.pipe(res);
}
};
/**
* # CSV Helpers
*/
/**
* @method CSV Escape
* @param {String} field
* @return {String}
*/
function csvEscape (field) {
return '"' + String(field || "").replace(/"/g, '""') + '"';
}
/**
* @method Array to Single CSV Row
* @param {Array} array A list of fields
* @return {String} One row of a CSV file
*/
function array2csvRow (array) {
return array.map(csvEscape).join(',')+'\n';
}
/**
* @method Array to CSV
* @param {Array} array An array of arrays (containing fields)
* @return {String} CSV representation
*/
function array2csv (array) {
return array.map(array2csvRow).join('');
}
module.exports = {
escape: csvEscape,
rowFromArray: array2csvRow,
fromArray: array2csv
};
@weisjohn
Copy link

Thanks for putting this up. I found it very helpful!

@zeroindex
Copy link

This was helpful for me too. Populate wasn't working for me, so I used cursor() instead of stream().
Team .find({accepted: true}) .populate({path: '_users'}) .cursor()

@dwaxgio
Copy link

dwaxgio commented Jun 10, 2021

Thank you, this part was specially helpful:

res.writeHead(200, { 'Content-Type': 'text/csv', 'Content-Disposition': 'attachment; filename=export.csv' });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment