#python #json #python-3.x #excel #sharepoint
#python #json #python-3.x #excel #sharepoint
Вопрос:
В Python я использую клиентскую библиотеку Office 365 REST Python для доступа и чтения книги Excel, содержащей много листов.
Хотя аутентификация прошла успешно, я не могу добавить правильный путь к имени листа к имени файла, чтобы получить доступ к 1-му или 2-му рабочему листу по его имени, поэтому вывод с листа — это не JSON, а байты ввода-вывода, которые мой код не может обработать.
Моя конечная цель — просто получить доступ к конкретному рабочему листу по его имени ’employee_list’ и преобразовать его в фрейм данных JSON или Pandas для дальнейшего использования.
Фрагмент кода ниже —
import io
import json
import pandas as pd
from office365.runtime.auth.authentication_context import AuthenticationContext
from office365.runtime.auth.user_credential import UserCredential
from office365.runtime.http.request_options import RequestOptions
from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.files.file import File
from io import BytesIO
username = 'abc@a.com'
password = 'abcd'
site_url = 'https://sample.sharepoint.com/sites/SAMPLE/_layouts/15/Doc.aspx?OR=teamsamp;action=editamp;sourcedoc={739271873}'
# HOW TO ACCESS WORKSHEET BY ITS NAME IN ABOVE LINE
ctx = ClientContext(site_url).with_credentials(UserCredential(username, password))
request = RequestOptions("{0}/_api/web/".format(site_url))
response = ctx.execute_request_direct(request)
json_data = json.loads(response.content) # ERROR ENCOUNTERED JSON DECODE ERROR SINCE DATA IS IN BYTES
Комментарии:
1. Вы пытаетесь сделать это из Microsoft Excel?
2. Нет, это таблица Excel для совместной работы на основе Sharepoint, доступная в командах
Ответ №1:
Вы можете получить к нему доступ по индексу листа, проверьте следующий код….
import xlrd
loc = ("File location")
wb = xlrd.open_workbook(loc)
sheet = wb.sheet_by_index(0)
# For row 0 and column 0
print(sheet.cell_value(1, 0))
Комментарии:
1. open_workbook не работает для ссылок на URL-адреса файлов Sharepoint Excel
2. Можно ли загрузить электронную таблицу из Teams / Sharepoint, сохранить ее в
io.BytesIO
буфере, а затем использоватьxlrd.open_workbook(buffer)
? Затем повторно загрузить его?3. Обратите внимание, что xlrd поддерживает только файлы xls, начиная с версии 2.0. Рассмотрите возможность использования вместо этого openpyxl (или pandas.read_excel / pandas ExcelFile). Файл может быть загружен в объект BytesIO и передан любому из этих параметров.
Ответ №2:
Вы можете попробовать добавить компонент ‘sheetname’ к URL-адресу следующим образом.
https://site/lib/workbook.xlsx#'Sheet1'!A1
Ответ №3:
Кажется, что URL, созданный для доступа к данным, неверен. Вы должны проверить полный URL в своем браузере как рабочий, а затем изменить код, чтобы начать работу. Вы можете попробовать это с некоторыми изменениями, я проверил, что URL, сформированный с помощью этой логики, вернет данные JSON.
import io
import json
import pandas as pd
from office365.runtime.auth.authentication_context import AuthenticationContext
from office365.runtime.auth.user_credential import UserCredential
from office365.runtime.http.request_options import RequestOptions
from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.files.file import File
from io import BytesIO
username = 'abc@a.com'
password = 'abcd'
site_url = 'https://sample.sharepoint.com/_vti_bin/ExcelRest.aspx/RootFolder/ExcelFileName.xlsx/Model/Ranges('employee_list!A1|A10')?$format=json'
# Replace RootFolder/ExcelFileName.xlsx with actual path of excel file from the root.
# Replace A1 and A10 with actual start and end of cell range.
ctx = ClientContext(site_url).with_credentials(UserCredential(username, password))
request = RequestOptions(site_url)
response = ctx.execute_request_direct(request)
json_data = json.loads(response.content)
Ответ №4:
Обновление, которое я использую ( Office365-REST-Python-Client==2.3.11
), позволяет упростить доступ к файлу Excel в репозитории SharePoint.
# from original_question import pd,
# username,
# password,
# UserCredential,
# File,
# BytesIO
user_credentials = UserCredential(user_name=username,
password=password)
file_url = ('https://sample.sharepoint.com'
'/sites/SAMPLE/{*recursive_folders}'
'/sample_worksheet.xlsx')
## absolute path of excel file on SharePoint
excel_file = BytesIO()
## initiating binary object
excel_file_online = File.from_url(abs_url=file_url)
## requesting file from SharePoint
excel_file_online = excel_file_online.with_credentials(
credentials=user_credentials)
## validating file with accessible credentials
excel_file_online.download(file_object=excel_file).execute_query()
## writing binary response of the
## file request into bytes object
Теперь у нас есть двоичная копия файла Excel с BytesIO
именем excel_file
. Продвигаясь, чтение его как pd.DataFrame
происходит просто, как обычный файл Excel, хранящийся на локальном диске. Например.:
pd.read_excel(excel_file) # -> pd.DataFrame
Следовательно, если вас интересует конкретный лист, подобный 'employee_list'
, вы можете предпочтительно прочитать его как
employee_list = pd.read_excel(excel_file,
sheet_name='employee_list')
# -> pd.DataFrame
или
data = pd.read_excel(excel_file,
sheet_name=None) # -> dict
employee_list = data.get('employee_list')
# -> [pd.DataFrame, None]
Комментарии:
1. знаете ли вы, как обновить «данные», а затем передать обновление в Excel-> обновить Excel в sharepoint, а не просто читать
2. Я не уверен, но у меня есть предположение об этом, @ErikJohnsson. Если
.download
функция позволяет читать, то существует предполагаемая.upload
функция, которая позволяет записывать.
Ответ №5:
Я знаю, что вы заявили, что не можете использовать объект BytesIO, но для тех, кто приходит сюда и читает файл в качестве объекта BytesIO, который я искал, вы можете использовать sheet_name
аргумент в pd.read_excel
:
url = "https://sharepoint.site.com/sites/MySite/MySheet.xlsx"
sheet_name = 'Sheet X'
response = File.open_binary(ctx, relative_url)
bytes_file_obj = io.BytesIO()
bytes_file_obj.write(response.content)
bytes_file_obj.seek(0)
df = pd.read_excel(bytes_file_obj, sheet_name = sheet_name) //call sheet name