
本文介绍解决 pandas `read_excel` 函数因直接传入字节数据(bytes)而触发弃用警告的问题,推荐使用 `bytesio` 封装字节流以构造文件类对象,确保代码兼容未来版本。
当从云存储(如 Azure Blob Storage、AWS S3)或内存中读取 Excel 文件时,常通过 .readall() 或 .getvalue() 获取原始字节(bytes),但 pandas.read_excel() 已明确弃用直接接收 bytes 类型参数的方式,否则会抛出如下警告:
FutureWarning: Passing bytes to 'read_excel' is deprecated and will be removed in a future version. To read from a byte string, wrap it in a `BytesIO` object.
✅ 正确做法是将字节数据包装为类文件对象(file-like object),io.BytesIO 是标准且轻量的解决方案:
from io import BytesIO import pandas as pd # 假设 blob_data 是来自 Azure BlobServiceClient 的 BlobClient 下载响应 # 或其他返回 bytes 的源(如 requests.get(...).content) excel_bytes = blob_data.readall() # type: bytes # ✅ 关键:用 BytesIO 包装字节流,使其支持 seek()/read() 等文件操作 df = pd.read_excel(BytesIO(excel_bytes), engine='openpyxl')
? 补充说明与最佳实践:
- 引擎选择:engine='openpyxl' 适用于 .xlsx/.xlsm 文件;若处理旧版 .xls,请改用 engine='xlrd'(注意:xlrd ≥ 2.0 仅支持 .xls,已不再支持 .xlsx);
- 内存效率优化:若文件较大,避免一次性 .readall() 加载全部内容,可改用流式读取(如 BytesIO(blob_data.read()) 配合分块逻辑),但 read_excel 本身暂不支持真正流式解析,因此 BytesIO 仍是当前最通用、最稳定的方案;
- 替代库? 目前无主流替代库能绕过此封装步骤——openpyxl、xlrd、pyxlsb 等底层引擎均要求文件路径或类文件对象,而非裸字节;pandas 作为统一接口层,其设计正是基于此约定;
- 扩展场景:该模式同样适用于 pd.read_csv()、pd.read_json() 等函数处理内存中的二进制数据。
? 总结:不要传 bytes,要传 BytesIO(bytes) —— 这不是权宜之计,而是 Pandas 官方推荐的标准化做法,兼顾向后兼容性与代码健壮性。










