Last active
June 10, 2021 22:02
-
-
Save killercup/11256050 to your computer and use it in GitHub Desktop.
Streamed CSV Export using node-restify and mongoose
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* # 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); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* # 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 | |
}; |
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()
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
Thanks for putting this up. I found it very helpful!