You need to enable JavaScript to run this app. Node.js服务端实现全格式Excel文件上传下载至Azure Blob Storage及问题解决
优惠活动
大模型
产品
解决方案
定价
更多

Node.js服务端实现全格式Excel文件上传下载至Azure Blob Storage及问题解决

上传问题根因
  • blockBlobClient.upload()方法的第一个入参要求传入文件实际内容(支持Buffer、可读流、二进制字符串类型),SDK不会自动解析传入的路径为本地文件,所有传入该方法的内容都会被直接作为Blob的存储数据。当前代码传入的是拼接后的本地临时文件路径字符串,因此Blob存储的仅为该路径文本,不是Excel的实际二进制内容。
  • 未对multer生成的临时磁盘文件做内容读取,直接将路径作为上传数据源传递。
上传逻辑修复步骤
  1. 引入Node.js内置fs模块的文件流读取能力,读取临时文件的二进制内容
  2. 显式指定Blob的HTTP头,匹配Excel文件的MIME类型,避免下载时类型识别异常
  3. 移除upload入参中无意义的容器名拼接逻辑

修复后的上传核心代码:

import { DefaultAzureCredential } from '@azure/identity';
import { BlobServiceClient } from '@azure/storage-blob';
// 新增:引入fs模块的文件流方法
import { createReadStream } from 'fs';

const account = process.env.ACCOUNT_NAME;
const containerName = process.env.CONTAINER_NAME;

if (
  !process.env.AZURE_TENANT_ID ||
  !process.env.AZURE_CLIENT_ID ||
  !process.env.AZURE_CLIENT_SECRET || !account || !containerName
) {
  return next(SystemResponse.badRequestError('Azure AD authentication information not provided, but it is required to run this sample. Exiting.'));
}

const defaultAzureCredential = new DefaultAzureCredential();
const blobServiceClient = new BlobServiceClient(
  `https://${account}.blob.core.windows.net`,
  defaultAzureCredential,
);
const containerClient = blobServiceClient.getContainerClient(containerName);

// 生成Blob名称的逻辑保持不变
const blobName = `${req.files.file.name.split('.')[0]}+${new Date().getTime()}.${req.files.file.name.split('.')[1]}`;
const blockBlobClient = containerClient.getBlockBlobClient(blobName);

// 替换原错误的upload调用
const fileStream = createReadStream(req.files.file.path);
const uploadBlobResponse = await blockBlobClient.upload(
  fileStream,
  req.files.file.size,
  {
    // 显式指定Excel的Content-Type
    blobHTTPHeaders: {
      blobContentType: req.files.file.mimetype
    }
  }
);

如果使用multer的内存存储模式(无临时磁盘文件),可直接将req.files.file.buffer作为upload的第一个入参传入,无需额外读取文件流。

下载逻辑修复

当前下载仅返回文件名,是因为未正确将Blob的二进制流通过HTTP响应输出,需按以下逻辑调整:

  • 从Blob获取读取流
  • 设置正确的HTTP响应头,告知客户端返回的是附件下载
  • 将Blob流管道到响应对象,直接输出二进制内容

示例下载代码:

// 传入对应Blob的名称获取客户端
const targetBlobClient = containerClient.getBlockBlobClient(targetBlobName);
const downloadRes = await targetBlobClient.download();

// 设置响应头,触发浏览器文件下载
res.setHeader('Content-Type', downloadRes.contentType);
res.setHeader(
  'Content-Disposition',
  `attachment; filename="${encodeURIComponent(targetBlobName)}"`
);
res.setHeader('Content-Length', downloadRes.contentLength);

// 将Blob的可读流直接输出到响应
downloadRes.readableStreamBody.pipe(res);

内容的提问来源于stack exchange,提问作者Hemendra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.09 06:36:04