-1

I'm trying to zip multiple files on a server and download it when user requests it. I am using adm-zip to zip files.

Files add perfectly fine and are zipped. zip.writeZip('') zipes files perfectly and saves them to local server. I am just unable to download them. Either way I think it would be better if I could send zip directly via buffer.

router.get(
  "/download-zip/:season_id/:club_id",
  passport.authenticate("jwt", { session: false }),
  (req, res) => {
    FileSubmission.find({
      season: req.params.season_id,
      club: req.params.club_id
    }).then(files => {

      const zip = new AdmZip();

      files.forEach(file => {
        // add local file
        zip.addLocalFile(`uploads/club-uploads/${file.club}/${file.name}`);
      });

      res.download(zip.toBuffer(), "asd.zip");
    });
  }
);

On the front I am using react with actions and js-file-download library


// Download ALL FILES by season ID and club ID
import fileDownload from "js-file-download";

export const downloadAllFiles = (season_id, club_id) => dispatch => {
  axios
    .get(`/api/files/download-zip/${season_id}/${club_id}`)
    .then(response => {
      fileDownload(response.data, `All Files- ${club_id}.zip`);
    })
    .catch(err => {
      console.log(err);
      dispatch({ type: GET_ERRORS, payload: err.response.data });
    });
};
  • Looking at your code, it appears it's not `async`.. Just a big warning here, if using express and if what's been zipped is big, all users of your web application are going to suffer. Maybe look into moving some of this into some sort of cluser or server worker. Ps, also turning your webserver to use clusters will only mean it shifts the problems to all users connected to a particular cluster. – Keith Oct 15 '19 at 12:56

1 Answers1

0

Here's how I managed to create temporary archive, download it and delete it.

Here's back-end

// Create a ZIP of files uploaded by a club
router.get(
  "/download-zip/",
  (req, res) => {
      zip.addLocalFile(/*ADD THE FILES TO ZIP*/);

      zip.writeZip(
        `temp/zips/temp-file.zip`,
        err => {
          if (err) {
            console.log(err);
          }

          res.download(
            `uploads/club-zips/test-file.zip`,
            function(err) {
              if (!err) {
                //delete file after it's been downloaded
                fs.unlinkSync(
                  `uploads/club-zips/test-file-${req.params.club_id}.zip`
                );
              }
            }
          );
        }
      );
    });
  }
);

Here's what I use on front. As I said I used package called js-file-download to download blobs

export const downloadAllFiles = () => dispatch => {
  axios
    .get(`/api/files/download-zip/`, {
      responseType: "arraybuffer"
    })
    .then(response => {
      fileDownload(response.data, `all-files.zip`);
    })
    .catch(err => {
      console.log(err);
    });
};
Nimantha
  • 6,405
  • 6
  • 28
  • 69