从SharePoint下载Excel存为网页而非Excel的技术求助
问题根源
你下载的不是真实的Excel文件,而是SharePoint的网页内容(存为html能打开就是证明),这说明当前代码获取的不是文件流,而是错误页、登录重定向页这类网页数据,自然无法被Excel或openpyxl识别。
修复方案
1. 修正服务器相对路径
确保file_url以斜杠/开头,SharePoint的服务器相对路径通常需要根路径标识:
file_url = "/Shared Documents/Messages/File_to_Download.xlsx"
2. 验证下载内容是否为Excel
先检查下载文件的前几个字节,确认是否为Zip格式(xlsx本质是Zip包,开头字节应为PK\x03\x04):
with open("x.xlsx", "rb") as f: print(f.read(4)) # 输出b'PK\x03\x04'才是正确的Excel文件
如果输出不是这个,说明路径或权限有问题,需要确认文件存在、账号有访问权限。
3. 使用直接URL请求下载(更可靠的方式)
通过ClientContext获取文件的直接下载URL,再用requests库结合凭据下载:
from office365.runtime.auth.user_credential import UserCredential from office365.sharepoint.client_context import ClientContext import requests def get_excel_from_link(url=None): user_credentials = UserCredential(username, password) ctx = ClientContext(url).with_credentials(user_credentials) # 获取文件对象 file_url = "/Shared Documents/Messages/File_to_Download.xlsx" file = ctx.web.get_file_by_server_relative_path(file_url).get().execute_query() # 获取直接下载URL download_url = file.serverRelativeUrl # 构造完整请求URL full_download_url = f"{url}{download_url}" # 使用requests下载,复用账号凭据 session = requests.Session() session.auth = (username, password) # 添加强制获取Excel格式的请求头 headers = { "Accept": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" } response = session.get(full_download_url, headers=headers, stream=True) response.raise_for_status() # 检查请求是否成功 # 保存文件 download_path = "x.xlsx" with open(download_path, "wb") as local_file: for chunk in response.iter_content(chunk_size=8192): local_file.write(chunk)
4. 直接用BytesIO处理(无需保存到本地)
如果不需要本地文件,可直接在内存中用openpyxl处理:
from io import BytesIO import openpyxl # 接上面的response对象 excel_data = BytesIO(response.content) wb = openpyxl.load_workbook(excel_data) # 后续可直接操作工作簿,比如读取工作表 sheet = wb.active print(sheet["A1"].value)
关键说明
BadZipFile错误是因为下载内容是网页文本而非Zip格式的xlsx文件,修复下载流程后该错误会自动消失。- 若使用SharePoint Online,若用户权限方式无法正常获取文件,可考虑改用应用权限的
ClientCredential方式认证。
内容的提问来源于stack exchange,提问作者darthsithius
相关产品推荐
相关产品推荐

