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

NestJS上传Excel解析时file.buffer读取报错解决方案

问题根因

file.buffer读取时报错,由两处代码错误直接导致:

  • 上传接口重复注册了两次FileInterceptor拦截器:一个传入自定义multer配置,一个无任何配置,后者会覆盖前者的配置生效
  • 自定义multer配置使用diskStorage磁盘存储模式:该模式下Multer会将上传文件写入本地磁盘,返回的file对象仅包含文件存储路径、原始文件名等元信息,不会生成buffer二进制字段。file.buffer仅在Multer使用默认memoryStorage内存存储模式时才会存在。
修复步骤
  1. 删除接口上重复的无配置@UseInterceptors(FileInterceptor('file'))装饰器,仅保留传入multerOptions的拦截器
  2. 根据业务需求调整存储配置:
    • 如果不需要在服务端持久化存储原始上传文件,直接将multer的存储模式改为memoryStorage,即可直接读取file.buffer做Excel解析
    • 如果需要持久化存储原始文件,保留diskStorage配置,改为通过文件系统接口读取本地存储的文件内容后再做解析
  3. (可选优化)原文件类型校验的正则匹配逻辑存在误判风险,建议改为扩展名+MIME类型双重精确校验,同时给文件大小配置加默认值,避免环境变量未定义导致配置异常。
修复后代码示例

上传接口代码

@Post('upload')
@UseInterceptors(FileInterceptor('file', multerOptions))
UploadExcelFile(@UploadedFile() file: Express.Multer.File) {
  console.log("Hello")
  console.log(file);
  const workBook: XLSX.WorkBook = XLSX.read(file.buffer, {
    type: 'buffer',
    cellDates: true,
    cellNF: false,
  });
  const sheetName = workBook?.SheetNames[0];
  const sheet: XLSX.WorkSheet = workBook.Sheets[sheetName];
  
  const jsonData: FileUploadDto[] = XLSX.utils.sheet_to_json(sheet, {
    dateNF: 'YYYY-MM-DD',
  });
  // 后续补充字段校验、入库逻辑
  console.log(jsonData);
  // return this.usersService.processFile(file);
}

multer配置(内存存储模式,适配buffer直接读取)

import { extname } from 'path';
import { memoryStorage } from 'multer';
import { HttpException, HttpStatus } from '@nestjs/common';

export const multerOptions = {
    limits: {
        // 增加默认值,避免环境变量未读取到导致大小限制异常
        fileSize: +process.env.MAX_FILE_SIZE || 5 * 1024 * 1024,
    },
    fileFilter: (_req: any, file: any, callback: any) => {
        const allowedExts = ['.jpg','.jpeg','.png','.gif','.pdf','.msg','.eml','.docx','.doc','.xlsx','.xls'];
        const fileExt = extname(file.originalname).toLowerCase();
        const allowedMimes = [
          'image/jpeg','image/png','image/gif','application/pdf',
          'application/vnd.ms-outlook','message/rfc822',
          'application/msword','application/vnd.openxmlformats-officedocument.wordprocessingml.document',
          'application/vnd.ms-excel','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        ];
        if (allowedExts.includes(fileExt) && allowedMimes.includes(file.mimetype)) {
            callback(null, true);
        } else {
            callback(
                new HttpException(
                    `Unsupported file type ${fileExt}`,
                    HttpStatus.BAD_REQUEST
                ),
                false
            );
        }
    },
    // 替换为内存存储,自动生成file.buffer字段
    storage: memoryStorage(),
};

若需保留磁盘存储逻辑,无需修改multer配置,将接口内读取buffer的逻辑替换为磁盘文件读取即可:

import * as fs from 'fs/promises';
// 接口内获取文件后读取内容
const fileBuffer = await fs.readFile(file.path);
const workBook: XLSX.WorkBook = XLSX.read(fileBuffer, {
  type: 'buffer',
  cellDates: true,
  cellNF: false,
});
// 后续Excel解析逻辑与之前一致

上传解析对应DTO

import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsString, MaxLength } from 'class-validator';

export class FileUploadDto {
  @IsString()
  @IsNotEmpty()
  @MaxLength(25)
  displayName: string;

  @IsString()
  @IsNotEmpty()
  @MaxLength(25)
  email: string;

  @IsString()
  @IsNotEmpty()
  @MaxLength(50)
  role: string;
}
问题复现材料
  • 接口报错截图:接口报错截图
  • 测试Excel文件内容:Excel文件内容截图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 08:57:18