Blob触发Azure函数无法读取部分Excel文件求助
解决方案:处理伪装成Excel的CSV文件导致的XLRDError
这个问题我之前帮团队排查过,本质是部分上传的文件并非真正的Excel格式——它们是被修改了后缀名的CSV文件(还带UTF-8 BOM),导致pandas.read_excel无法识别,抛出XLRDError。
错误原因拆解
你看到的错误信息Exception: XLRDError: Unsupported format, or corrupt file: Expected BOF record; found b'\xef\xbb\xbfName,'是关键:
\xef\xbb\xbf是UTF-8编码的字节顺序标记(BOM),常见于Windows导出的CSV文件- 后面的
Name,是典型的CSV表头开头,说明文件实际内容是CSV,但后缀被改成了.xlsx或.xls
那些能正常读取的文件是真正的Excel格式,而失败的都是"伪装"的CSV,这就是为什么没有固定失败规律——完全取决于上传者的文件类型。
修复方案:兼容Excel和CSV(含带BOM的CSV)
我们可以让函数同时支持两种格式:先尝试用Excel方式读取,失败则自动降级为CSV读取,同时处理UTF-8 BOM问题。修改后的代码如下:
import pandas as pd import azure.functions as func import logging from xlrd import XLRDError def main(myblob: func.InputStream): logging.info(f"Python blob trigger function processed blob \n" f"Name: {myblob.name}\n" f"Blob Size: {myblob.length} bytes") # 重置流指针到开头:避免之前的读取操作导致后续读取为空 myblob.seek(0) try: # 优先尝试读取为Excel文件 data = pd.read_excel(myblob) logging.info(f"Successfully read {myblob.name} as Excel") except XLRDError as e: # Excel读取失败,尝试读取为带UTF-8 BOM的CSV logging.warning(f"Failed to read {myblob.name} as Excel: {str(e)}. Trying CSV format...") myblob.seek(0) # 再次重置指针,因为第一次读取已经把流读到末尾 # 使用utf-8-sig编码自动去除UTF-8 BOM data = pd.read_csv(myblob, encoding='utf-8-sig') logging.info(f"Successfully read {myblob.name} as CSV") # 将NaN替换为None,保持原有逻辑 data = data.where(pd.notnull(data), None) # 后续处理逻辑 # ...
额外优化建议
- 增加后缀名判断:可以先根据文件后缀名初步选择读取方式,减少异常捕获的次数,比如:
file_ext = myblob.name.split('.')[-1].lower() if file_ext in ['csv']: # 直接读取为CSV myblob.seek(0) data = pd.read_csv(myblob, encoding='utf-8-sig') else: # 尝试Excel读取 try: myblob.seek(0) data = pd.read_excel(myblob) except XLRDError: # 降级为CSV读取 myblob.seek(0) data = pd.read_csv(myblob, encoding='utf-8-sig') - 增加文件校验:如果需要严格区分文件类型,可以通过检测文件的魔术字节(magic bytes)来判断是否为真正的Excel文件(比如
.xlsx的开头是PK\x03\x04),避免完全依赖后缀名。 - 告知协作人员:提醒使用函数的同事,尽量上传真正的Excel文件,不要手动修改文件后缀名,从源头减少这类问题。
内容的提问来源于stack exchange,提问作者Grevioos
相关产品推荐
相关产品推荐

