Search code examples
downloadnestjszipazure-blob-storage

Download azure blob storage files as zipped folder


I am using azure blob storage with Nest.js for file handling.

Below is the download code:

const blobClient = this.getBlobClient(url);
const downloadBlockBlobResponse = await blobClient.download();
return downloadBlockBlobResponse.readableStreamBody;

getBlobClient(fileName: string): BlockBlobClient {
    const blobClient = containerClient.getBlockBlobClient(fileName);
    return blobClient;
}

File downloading is working fine. But I need to download the file into a zipped folder and return the blob result.

How to do that using Nest.js?


Solution

  • I need to download the file into a zipped folder

    You can use my Github link to get the code to download the file as a zip folder.

    app.service.ts

    import { Injectable } from '@nestjs/common';
    import { BlobServiceClient} from '@azure/storage-blob';
    import * as archiver from 'archiver';
    import { Readable } from 'stream';
     
     
    @Injectable()
    export class BlobStorageService {
       private readonly blobServiceClient: BlobServiceClient;
    
      constructor() {
        this.blobServiceClient = BlobServiceClient.fromConnectionString("Your storage connection string");
      }
    
      async downloadFileAsZip(containerName: string, fileName: string): Promise<Readable> {
        const containerClient = this.blobServiceClient.getContainerClient(containerName);
        const blobClient = containerClient.getBlockBlobClient(fileName);
        const downloadBlockBlobResponse = await blobClient.download();
    
        const archive = archiver('zip', { zlib: { level: 9 } });
        const stream = Readable.from(downloadBlockBlobResponse.readableStreamBody);
    
        archive.append(stream, { name: fileName });
        archive.finalize();
        return archive;
      }
    }
    

    app.controller.ts

    import { Controller, Get, Param, Res } from '@nestjs/common';
    import { Response } from 'express';
    import { BlobStorageService } from './app.service';
    
    @Controller()
    export class AppController {
      constructor(private readonly blobStorageService: BlobStorageService) {}
    
    @Get(':container/:fileName')
      async downloadFileAsZip(@Param('container') container: string, @Param('fileName') fileName: string, @Res() res: Response) {
        const stream = await this.blobStorageService.downloadFileAsZip(container, fileName);
        res.set({
          'Content-Type': 'application/zip',
          'Content-Disposition': `attachment; filename=${fileName}.zip`,
        });
        stream.pipe(res);
      }
    }
    

    Output: enter image description here

    To fetch the file as a zip folder you can use the below request:

    localhost:3000/<Your container name>/<Your file name>
    

    Browser: enter image description here