1

The front-end is written in ReactJS, more specifically grommet. There are multiple pdf files to be served to the user on clicking the Download button. The files are stored in GridFS. I wish to give the user a zipped folder which contains all these files. How can I achieve this?

Thanks in advance.

Ritik Saxena
  • 694
  • 1
  • 11
  • 23

1 Answers1

1

I have it!! Super simple solution with archiver. Worked at first time.

Note: I am using sails.js. DBFile is my Model.

const GridFsAdapter = require('../adapters/gridfs-adapter');
const archiver = require('archiver');

async function downloadMultiple (query, res, filename) {

  // create a stream for download
  const archive = archiver('zip', {
    zlib: {level: 9} // Sets the compression level.
  });

  // catch warnings (ie stat failures and other non-blocking errors)
  archive.on('warning', (err) => {
    if (err.code === 'ENOENT') {
      // log warning
      sails.log.warn(err);
    } else {
      // throw error
      throw err;
    }
  });

  archive.on('error', (err) => {
    throw err;
  });

  // set file name
  res.attachment(filename);
  
  // pipe the stream to response before appending files/streams
  archive.pipe(res);

  // add your streams
  await DBFile
    .stream(query)
    // like mongoDBs cursor.forEach() function. Avoids to have all record in memory at once
    .eachRecord(async (dbFile) => {
      // get the stream from db
      const {stream, data} = await GridFsAdapter().read(dbFile.fileId);
      // append stream including filename to download stream
      archive.append(stream, {name: data.filename});
    });

  // tell the download stream, you have all your files added
  archive.finalize();
}