You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Nest.js中将Azure Blob Storage文件打包为Zip下载

在Nest.js中实现Azure Blob文件打包下载

1. 安装依赖

首先安装处理压缩包的流式工具archiver,适配Azure Blob的流操作:

npm install archiver
npm install @types/archiver --save-dev

2. 改造服务层逻辑

在你的Blob存储服务中新增打包方法,通过流式操作直接将多个Azure Blob文件压缩成zip:

import { Injectable } from '@nestjs/common';
import { BlockBlobClient, ContainerClient } from '@azure/storage-blob';
import * as archiver from 'archiver';
import { PassThrough } from 'stream';

@Injectable()
export class BlobStorageService {
  private containerClient: ContainerClient;

  // 省略containerClient的初始化逻辑

  getBlobClient(fileName: string): BlockBlobClient {
    return this.containerClient.getBlockBlobClient(fileName);
  }

  async packFilesToZipStream(fileNames: string[]): Promise<PassThrough> {
    const zipArchive = archiver('zip', { zlib: { level: 9 } });
    const outputStream = new PassThrough();

    zipArchive.pipe(outputStream);

    // 遍历目标文件,逐个下载流并加入压缩包
    for (const name of fileNames) {
      const blobClient = this.getBlobClient(name);
      const downloadRes = await blobClient.download();
      zipArchive.append(downloadRes.readableStreamBody, { name });
    }

    // 完成压缩包写入
    await zipArchive.finalize();
    return outputStream;
  }

  // 如果需要返回Blob对象(而非直接响应给客户端)
  async packFilesToBlob(fileNames: string[]): Promise<Blob> {
    const zipArchive = archiver('zip', { zlib: { level: 9 } });
    const bufferChunks: Buffer[] = [];

    zipArchive.on('data', chunk => bufferChunks.push(chunk));

    for (const name of fileNames) {
      const blobClient = this.getBlobClient(name);
      const downloadRes = await blobClient.download();
      zipArchive.append(downloadRes.readableStreamBody, { name });
    }

    await zipArchive.finalize();
    return new Blob(bufferChunks, { type: 'application/zip' });
  }
}

3. 控制器层处理响应

在控制器中调用服务方法,设置正确的响应头,让客户端识别为zip文件:

import { Controller, Get, Res, Query } from '@nestjs/common';
import { Response } from 'express';
import { BlobStorageService } from './blob-storage.service';

@Controller('files')
export class FilesController {
  constructor(private readonly blobService: BlobStorageService) {}

  @Get('download-zip')
  async downloadPackedFiles(
    @Query('fileNames') fileNames: string[],
    @Res() res: Response,
  ) {
    // 设置响应头,指定文件名和内容类型
    res.setHeader('Content-Type', 'application/zip');
    res.setHeader('Content-Disposition', 'attachment; filename="packed-files.zip"');

    const zipStream = await this.blobService.packFilesToZipStream(fileNames);
    zipStream.pipe(res);
  }
}

核心说明

  • 全程采用流式处理,无需将文件下载到服务器本地,节省存储资源
  • PassThrough流用于桥接压缩包流和响应流,确保数据正确传递到客户端
  • 如果业务场景需要返回Blob对象而非直接响应,可使用packFilesToBlob方法

内容的提问来源于stack exchange,提问作者Code The World

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 15:30:13