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

Flask中无法读取POST请求传来的Excel文件问题排查

问题:AngularJS上传Excel到Flask解析时出现BadZipFile错误

尝试从AngularJS前端发送Excel文件到Flask应用并解析列,遇到以下错误:

File "/var/task/pandas/util/_decorators.py", line 296, in wrapper
    return func(*args, **kwargs)
  File "/var/task/pandas/io/excel/_base.py", line 304, in read_excel
    io = ExcelFile(io, engine=engine)
  File "/var/task/pandas/io/excel/_base.py", line 867, in __init__
    self._reader = self._engines[engine](self._io)
  File "/var/task/pandas/io/excel/_openpyxl.py", line 480, in __init__
    super().__init__(filepath_or_buffer)
  File "/var/task/pandas/io/excel/_base.py", line 351, in __init__
    self.book = self.load_workbook(filepath_or_buffer)
  File "/var/task/pandas/io/excel/_openpyxl.py", line 491, in load_workbook
    return load_workbook(
  File "/mnt/accesspoint/openpyxl/reader/excel.py", line 315, in load_workbook
    reader = ExcelReader(filename, read_only, keep_vba,
  File "/mnt/accesspoint/openpyxl/reader/excel.py", line 124, in __init__
    self.archive = _validate_archive(fn)
  File "/mnt/accesspoint/openpyxl/reader/excel.py", line 96, in _validate_archive
    archive = ZipFile(filename, 'r')
  File "/var/lang/lib/python3.8/zipfile.py", line 1269, in __init__
    self._RealGetContents()
  File "/var/lang/lib/python3.8/zipfile.py", line 1364, in _RealGetContents
    raise BadZipFile("Bad magic number for central directory")
zipfile.BadZipFile: Bad magic number for central directory

同时尝试用with open(file, 'rb') as f读取文件时,触发错误:TypeError: expected str, bytes or os.PathLike object, not FileStorage


相关代码

AngularJS HTML代码

<nz-card nzTitle="Upload File" bordered={false} style="flex: 1 1 auto;">
            <nz-upload 
            [nzCustomRequest]="handleUpload"
            [(nzFileList)]="fileList" 
            (nzChange)="handleChange($event)"
            [nzDownload]="handleDownload"
            [nzAccept]="fileType"
            >
                <p class="ant-upload-drag-icon"><i nz-icon nzType="inbox"></i></p>
                <p class="ant-upload-text">
                    Click or drag CSV/Excel a file to this area to upload
                </p>
            </nz-upload>
        </nz-card>

AngularJS组件代码

handleUpload = (item: any) => {
    const formData = new FormData();
    formData.append(item.name, item.file);

    var upload = this.httpClient.post(this.SERVER_URL, formData).subscribe(
      (res) => {
        console.log("success");
        item.onSuccess(item.file);
        if (typeof (res) === 'object') {
          console.log(res);
        }
        item.file;
      },
      (err) => {
        console.log("failure")
        item.onError(err, item.file);
      }
    )
}

Flask Python代码

def upload():
    file = request.files['file']
    print("request", file)

    df = pd.read_excel(file, index_col=0, engine='openpyxl')
    print(df)

错误前日志

request <FileStorage: 'sample_excel.xlsx' ('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')> 

原因分析

  • FormData键名不匹配:前端用formData.append(item.name, item.file)添加文件,但后端通过request.files['file']获取,若item.name不是'file',后端实际获取的文件内容为空或无效,导致pandas读取时无法识别为有效的Zip格式(xlsx本质是压缩包)。
  • FileStorage对象使用错误:Flask的FileStorage是类文件对象,不能直接作为路径传给open()函数,需要通过文件流或保存为本地文件来处理。

解决方案

  1. 修正前端FormData键名
    确保前端FormData的键名和后端获取的键名一致,修改AngularJS组件代码:

    handleUpload = (item: any) => {
        const formData = new FormData();
        // 明确指定键名为'file',和后端request.files['file']对应
        formData.append('file', item.file);
    
        var upload = this.httpClient.post(this.SERVER_URL, formData).subscribe(
          (res) => {
            console.log("success");
            item.onSuccess(item.file);
            if (typeof (res) === 'object') {
              console.log(res);
            }
          },
          (err) => {
            console.log("failure")
            item.onError(err, item.file);
          }
        )
    }
    
  2. 后端正确处理FileStorage对象
    方案一:直接读取文件流(需重置文件指针到开头)

    def upload():
        file = request.files['file']
        # 重置文件指针到起始位置,避免因文件指针偏移导致读取空内容
        file.seek(0)
        df = pd.read_excel(file, index_col=0, engine='openpyxl')
        print(df)
    

    方案二:先保存文件再读取

    def upload():
        file = request.files['file']
        # 将文件保存到本地临时路径
        file.save('temp_upload.xlsx')
        df = pd.read_excel('temp_upload.xlsx', index_col=0, engine='openpyxl')
        print(df)
    
  3. 额外检查项

    • 确认上传的Excel文件未损坏,可手动打开验证有效性;
    • 确保Angular发送请求时,HttpClient自动设置了Content-Type: multipart/form-data(发送FormData时会自动处理,无需手动添加)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:24:17