使用Python上传到SharePoint后Excel文件损坏

7 投票
2 回答
2812 浏览
提问于 2025-04-18 09:18

我正在尝试用Python中的Requests模块把一个Excel文件从本地文件夹上传到Sharepoint。这个文件会出现在我的共享文档文件夹里,这正是我想要的地方。但是,当我尝试打开这个文件时,出现了一个提示:“您选择的工作簿无法打开。这个工作簿可能是一个不支持的文件格式,或者它可能已损坏。您想尝试在Excel中打开这个文件吗?”

我研究过这个问题,发现很多论坛提到一个常见的问题是文件中某个地方有一个空格在^符号前面。不过目前为了测试,我只是想上传一个完全空白的文件,里面什么都没有。

这是我的代码:

files = {'file': ('Test.xlsx', open('Test.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}
myFile = requests.put('http://linkToMySharepoint/Test.xlsx', files=files, auth=auth)

我哪里做错了呢?任何帮助或建议都非常感谢!

2 个回答

0

我一开始也和你一样,遇到了同样的错误。当我仔细检查那个损坏的文件时,发现它的顶部有一些MIME元数据。这让我找到了正确的方向。其实只需要一个简单的PUT请求就可以了。下面是一个最简单的工作示例:

import requests
import os
import sys
from requests_ntlm import HttpNtlmAuth

filename = 'test.xlsx'


session = requests.Session()
session.auth = HttpNtlmAuth('YOURDOMAIN\\youraccount','yourpass', session)

file = open(filename, 'rb')
bytes = bytearray(file.read())
resp = requests.put('http://sharepoint.company.com/exampleurl/Archive%20%20old%20stuff/' + filename, data=bytes, auth=session.auth)

print(resp.status_code)
2

问题: 问题在于,Sharepoint 需要从你的请求中接收二进制数据。但你发送的是某种数据批次。当你发起请求时,python-requests 库会自动在请求头中添加一些内容。

Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryNTIFeyYj307EY4HV 

举个例子,试着发送一个包含“fcvsdcvsd”文本的 .txt 文件。当你把这个文件上传到你的 Sharepoint 网站时,你会收到一个不同的文件。这是我在 Sharepoint 文件库中上传该文件后得到的结果:

------WebKitFormBoundaryCGYE31vAG1tfvbzV
Content-Disposition: form-data; name="fileUpload1"; filename="testtest.txt"
Content-Type: text/plain

fcvsdcvsd
------WebKitFormBoundaryCGYE31vAG1tfvbzV-- 

在你的情况下,这些额外的内容也被添加到了你的文件中。当 Excel 尝试打开这个文件时,它发现了这些内容,结果就停止读取,因为文件被认为是损坏的。

解决方案: 正如我之前所说,你需要将文件作为二进制数据发送到请求的主体中。下面是我怎么做的:

   headers = {"accept": "application/json;odata=verbose",
               "X-RequestDigest": token,
               "content-type": "application/x-www-urlencoded; charset=UTF-8"}

    with open(local_path, "rb") as read_file:
        content = read_file.read() 

    r = requests.post(url + "getFolderByServerRelativeUrl('" + location + "')/files/add(overwrite=true,url='" + filename + "')",
                      data=content, auth=auth, headers=headers)

你可以看到,我将文件作为二进制数据(“content”)放在请求的主体(“data 参数”)中,并且内容类型被定义为“application/x-www-urlencoded; charset=UTF-8”。

这是我作为二进制数据发送的 txt 文件:

fcvsdcvsd

url 变量是你的 Sharepoint 服务器网关的地址(?)。 location 变量是你想要添加新文件的路径。 “X-RequestDigest”: token 是一个可选参数,如果你有权限访问你的 Sharepoint 服务器的话。

撰写回答