如何在AWS Lambda中读取请求体中的Excel文件?解决BadZipFile错误
解决FastAPI读取上传Excel文件时的BadZipFile错误
错误原因
你当前代码的核心问题是把二进制格式的Excel文件当成文本读取:
- Excel(尤其是
.xlsx)本质是Zip压缩包,属于二进制文件,不能用part.text获取内容——这个方法会将原始二进制字节流按文本编码解析,破坏文件结构,导致后续pd.read_excel无法识别为合法的Zip文件,抛出BadZipFile错误。
正确解决方案
方案1:直接使用FastAPI的UploadFile(推荐)
FastAPI已经帮你处理了Multipart文件上传的解析,无需手动解码request body,直接用UploadFile对象的file属性即可:
from fastapi import File, UploadFile, Depends from sqlalchemy.orm import Session import pandas as pd def upload_file(file: UploadFile = File(...), db: Session = Depends(get_db)): # 根据文件后缀选择引擎:.xls用xlrd,.xlsx用openpyxl engine = "xlrd" if file.filename.endswith(".xls") else "openpyxl" # 直接传入UploadFile的类文件对象 excel_data = pd.read_excel(file.file, engine=engine) pc_sheet_names = excel_data.sheet_names # 后续业务逻辑...
方案2:手动解析Multipart(仅特殊场景使用)
如果必须手动处理request body,需读取二进制内容而非文本:
from fastapi import Request, File, UploadFile, Depends from sqlalchemy.orm import Session import pandas as pd from multipart import decoder from io import BytesIO async def upload_file(request: Request, file: UploadFile = File(...), db: Session = Depends(get_db)): # 获取原始二进制请求体(注意用await,因为body()是异步方法) raw_body = await request.body() content_type = request.headers.get("Content-Type") for part in decoder.MultipartDecoder(raw_body, content_type).parts: # 读取二进制内容,而非文本 binary_content = part.content # 将二进制内容包装成类文件对象 file_like = BytesIO(binary_content) # 选择对应引擎读取 engine = "xlrd" if part.filename.endswith(".xls") else "openpyxl" excel_data = pd.read_excel(file_like, engine=engine) pc_sheet_names = excel_data.sheet_names # 后续业务逻辑...
注意事项
- 引擎选择:xlrd 2.0及以上版本不再支持
.xlsx格式,因此.xlsx文件必须用openpyxl引擎,.xls文件用xlrd引擎。 - 避免文本操作:所有二进制文件(Excel、图片、压缩包等)都不能用
text、decode等文本相关方法读取,必须保留原始字节流。
内容的提问来源于stack exchange,提问作者saraswathi moram
相关产品推荐
相关产品推荐

