0

Usually I create XLSX binary object by loading data from MongoDb. This is then streamed to the client in a http response. This is the code I use which works perfectly.

Server side code:

//Row data (rows) generated from database
 conf.rows = rows;

 //Only creates Headers from columns in existing data
 const data = lib.objectToSheet(conf);

 //Create sheet & workbook
 const ws = XLSX.utils.aoa_to_sheet(data, {cellDates: true});
 const wb = {SheetNames: ["MBS"], Sheets: {MBS: ws}};
 const wopts = {bookType: 'xlsx', bookSST: false, type: 'binary', compression:true};

 //Create binary data to write to client
 const wbout = XLSX.write(wb, wopts);
 const fileName = 'FileName.xlsx';

 //write workbook to client
 request.response.ContentType = "application/file";
 request.response.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8');
 request.response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
 request.response.end(wbout, 'binary');

In stead of streaming this back to the client I want to save the binary object (wbout) as a file in MongoDb GridFS so that this file can be downloaded to the client at a later stage.

I am planning to do the following

  1. create a file in memory on the server. let f = new FS.File(wbout);
  2. add properties (name, size, data, type)
  3. save file to mongo using a mongo collection

client side example where file is loaded from input control, I can access the same mongo collection on server for inserting a file.

 FS.Utility.eachFile(evt, function (file) {
    TempDocuments.insert(file, function (err, fileObject) {
    if (err) {
            console.log('Error: ', err);
        }
    });
 });

How do I go about to create a file from the binary object and save it directly to GridFS?

Do I need to create a file to the fileSystem into a temp location first or can I stream it to gridFS directly?

jqIndy
  • 414
  • 5
  • 11
  • I see the mongo collection does take a 'file|blob|buffer' as input parameter so the easiest would probably be to load the binary string into a blob object? – jqIndy Jan 15 '19 at 12:02

1 Answers1

1

Thanks to Agniva's post here (https://agniva.me/meteor/2016/04/25/meteor-arraybuffer.html) you can do the following:

 let buffer = new Buffer(wbout, "binary");
 let file = new FS.File();
 file.name(fileName);
 file.extension('xlsx');
 file.attachData(buffer, {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8'});

 if(file){
     //save wbout in gridfs
     TempDocuments.insert(file, function (err, fileObject) {
         console.log(err, fileObject);
     })
 } else {
    console.log('nofile');
 }

The only negative is that the file creates a random name. Not sure if this can be specified anywhere.

Edit: File properties can be set like the example above source: https://github.com/CollectionFS/Meteor-CollectionFS/wiki/FS.File

jqIndy
  • 414
  • 5
  • 11