In certain scenarios, we may need to zip the files in a folder and download as zip.
This can be achieved using a library archiver
in Nodejs.
What I am writing the article:
When I starting developing this feature, the issue faced was when the file is send as a response in the api, the zip file would be broken and not able to open.
I have up with the solution and would like to share in this article.
const app = express();
const port = 3000;
app.get('/download_folder', (req, res) => {
const folderPath = '/path/to/folder'; // Replace with the actual folder path
const zipName = 'folder.zip'; // Output file name in zip
const output = fs.createWriteStream(zipName); // create a write steam
const archive = archiver('zip');
// Pipe the archive data to the output file
archive.pipe(output);
// Read files from the folder and add them to the archive
fs.readdir(folderPath, (err, files) => {
if (err) {
console.error(err);
return res.status(500).send('Internal Server Error');
}
files.forEach(file => {
const filePath = `${folderPath}/${file}`;
archive.append(fs.createReadStream(filePath), { name: file });
});
// Finalize the archive and wait for the write stream to end
archive.finalize();
output.on('close', () => {
// Download the zip file as a response
res.attachment(zipName);
res.sendFile(zipName, { root: __dirname }, (err) => {
if (err) {
console.error(err);
return res.status(500).send('Internal Server Error');
}
// Delete the zip file after it is downloaded
fs.unlink(zipName, (err) => {
if (err) {
console.error(err);
}
});
});
});
});
});
app.listen(port, () => {
console.log(`Server is listening on port ${port}`);
});
The same logic can also be extended to support GCS from Google cloud platform.
For GCS download, we can create a folder as tmp in the working directory, then put the downloaded zip files in it and then send the response back to the api and finally remove the file in the tmp folder.
Hope this article is helpful.
Learn more Zip and download zip in a single API, NodeJS