Home » excel » Excel file corrupted after uploading to Sharepoint with Python

Excel file corrupted after uploading to Sharepoint with Python

Posted by: admin March 9, 2020 Leave a comment

Questions:

I am trying to upload an Excel file from a local folder to Sharepoint with the Requests module in Python. The file will appear in my Shared Documents folder, which is where I want it to be, but when I try to open the file, I get a message saying, “The workbook that you selected cannot be opened. The workbook may be in an unsupported file format, or it may be corrupt. Would you like to try and open this file in Excel?”

I have researched this problem, and many forums that I’ve found have said that a common problem is that there’s a space before a ^ symbol in the file somewhere, but at the moment, for testing purposes, I’m just trying to upload a completely blank file with absolutely nothing in it.

Here is my code:

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)

What am I doing wrong? Any help or insight would be greatly appreciated!

How to&Answers:

PROBLEM:
The problem is Sharepoint expects binary data from your request. But you are sending somekind batches of data. WHen you make request, python-requests library automatically adds to header

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

As example try to send .txt file with “fcvsdcvsd” text in it. When you upload this file to your Sharepoint site you will receive different file. This is what i got on Sharepoint file repository when I uploaded that file:

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

fcvsdcvsd
------WebKitFormBoundaryCGYE31vAG1tfvbzV-- 

In your case, these lines also added to your file. When Excel tries to open that file it finds these lines and stops reading as file is corrupted.

SOLUTION:
As I told before, you need to send file as binary in body of your request. Here is how I do it

   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)

As you can see I send file as binary(“content”) in body of request (“data parameter”) and Content type is defined as “application/x-www-urlencoded; charset=UTF-8”

Here is txt file i sent as binary

fcvsdcvsd

url variable is a url where your Sharepoint servers gateway is(?).
location variable is path where you want to add a new file
“X-RequestDigest”: token is an optional parameter, if you have authorization to access your Sharepoint server.

Answer:

I started out with what you did, and I got the same error. When I took a closer look at corrupt file, I discovered that it contained MIME meta data at the top. This put me on the right track. A plain PUT should suffice. Find below a minimal working example:

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)