Originally I want to use data in one excel file to update data in another excel file in sharepoint, while is split 3 steps.
implemented read excel file in sharepoint site.
implement writing changes to the excel file in sharepoint site.
need to implement reading from an excel and get data then use data to update anther excel.(not in the code below)
I know I should use Office365 API to read excel file in sharepoint. When I want to use openpyxl to do wb.save (), I got error:OSError: [Errno 22] Invalid argument. I don't know how to put absolute web url in save(). This is different with saving an excel in local drive. frustrated, appreciate it.
SP_SITE_URL ='https://companyname.sharepoint.com/sites/SiteName'
relative_url = "/sites/SiteName/Shared Documents/FolderName"
# 1. Create a ClientContext object and use the user’s credentials for authentication
ctx = ClientContext(SP_SITE_URL).with_user_credentials(USERNAME, PASSWORD)
ClientFolder = ctx.web.get_folder_by_server_relative_path(relative_url)
ctx.load(ClientFolder)
ctx.execute_query()
#if you want to get the files in the folder
files = ClientFolder.files
print(files)
ctx.load(files)
ctx.execute_query()
newest_file_url = ''
for myfile in files:
if myfile.properties["Name"] == 'Filename.xlsx':
newest_file_url = myfile.properties["ServerRelativeUrl"]
# Get Excel File by newest_file_url identified above
response= File.open_binary(ctx, newest_file_url)
# save data to BytesIO stream
bytes_file_obj = io.BytesIO()
bytes_file_obj.write(response.content)
bytes_file_obj.seek(0) # set file object to start
# load Excel file from BytesIO stream
wb = openpyxl.load_workbook(bytes_file_obj)
worksheet= wb['Sheet1']
# updates
row_count = worksheet.max_row
col_count = worksheet.max_column
for i in range(2,row_count+1):
for j in range(4,col_count + 1):
cellref=worksheet.cell(i, j)
cellref.value=datetime.today().strftime('%Y-%m-%d')
# save update to the file
wb.save('https://companyname.sharepoint.com/:x:/r/sites/SiteName/Shared%20Documents/FolderName/Filename.xlsx?d=xxxxx&csf=1&web=1&e=xxx')
Related
I have google drive IDs of many files which I want to download.
However the apis to download google drive files want the filename as well to save the file with that name.
Is there a way in python to get the title/name of the file from the google drive file ID in python?
If so please help to share a sample code.
The file.get method to download a file does not require a file name it simply requires that you send it the file id.
# Call the Drive v3 API
# get the file media data
request = service.files().get_media(fileId=FILEID)
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
print("Download %d%%" % int(status.progress() * 100))
What does require a name is when you want to save it to your system.
# The file has been downloaded into RAM, now save it in a file
fh.seek(0)
with open(file_name, 'wb') as f:
shutil.copyfileobj(fh, f, length=131072)
You can just do a file.get to get the metadata of the file first then you can use that when you want to save your file.
# Call the Drive v3 API
# Get file name, so we can save it as the same with the same name.
file = service.files().get(fileId=FILEID).execute()
file_name = file.get("name")
print(f'File name is: {file_name}')
I have a CSV that I want to put into a google sheet into sheet3 of many. I was hoping someone can help me complete this code. I am using Google API. So far I have gotten the csv to upload to the google drive. Now I would like to change the code to update a specific google sheet in sheet3 instead of creating a new sheet. Bellow you will find the code that I am using to create a new sheet with the CSV data.
# Import Csv to Google Drive
import os
import glob
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
gauth = GoogleAuth()
drive = GoogleDrive(gauth)
# line used to change the directory
os.chdir(r'DIRECTORY OF CSV')
list_of_files = glob.glob('DIRECTORY OF CSV\*') # * means all if need specific format then *.csv
latest_file = max(list_of_files, key=os.path.getctime)
print(latest_file)
upload_file_list = [latest_file]
for upload_file in upload_file_list:
gfile = drive.CreateFile({'parents': [{'id': 'THE GOOGLE ID'}]})
# Read file and set it as the content of this instance.
gfile.SetContentFile(upload_file)
gfile.Upload() # Upload the file.
I believe your goal is as follows.
You want to put CSV data to the specific sheet of a Google Spreadsheet.
You want to achieve this using python.
You have already been able to get and put values to the Spreadsheet using Sheets API.
In this case, how about the following sample script?
Sample script 1:
When googleapis for python is used, how about the following sample script?
service = build("sheets", "v4", credentials=creds) # Please use your script for authorization.
spreadsheet_id = "###" # Please put your Spreadsheet ID.
sheet_name = "Sheet3" # Please put the sheet ID of the sheet you want to use.
csv_file = "###" # Please put the file path of the CSV file you want to use.
f = open(csv_file, "r")
values = [r for r in csv.reader(f)]
request = service.spreadsheets().values().update(spreadsheetId=spreadsheet_id, range=sheet_name, valueInputOption="USER_ENTERED", body={"values": values}).execute()
Sample script 2:
When gspread for python is used, how about the following sample script?
import gspread
import csv
client = gspread.oauth(###) # Please use your script for authorization.
spreadsheet_id = "###" # Please put your Spreadsheet ID.
sheet_name = "Sheet3" # Please put the sheet ID of the sheet you want to use.
csv_file = "###" # Please put the file path of the CSV file you want to use.
spreadsheet = client.open_by_key(spreadsheet_id)
worksheet = spreadsheet.worksheet(sheet_name)
f = open(csv_file, "r")
values = [r for r in csv.reader(f)]
worksheet.update(values)
Note:
About both sample scripts, the CSV data is retrieved from a CSV file on your local PC, and the CSV data is converted to a 2-dimensional array and put the array to "Sheet3" of Google Spreadsheet using Sheets API. In this sample script, Drive API is not used.
Reference:
Method: spreadsheets.values.update
I am new to python. Kinldyhelp me to create a zipped csv file directly for the streaming data.
Details : My csv file should get updated each time a function is called. Instead of creating a .csv file i want to create a compressed .csv file for streaming data.
Note : My data is not generated in one go. df.to_csv(..., compression="gzip") does'nt work in my case.
Raising this question again , as my earlier question was marked duplicate and closed.
Trail1 :
def outputfile(result):
try:
table = pd.DataFrame(result)
table = table.transpose()
headers = ['IP','account', 'fd','instance_id','index','sourcetype','Product' , 'State']
if os.path.isfile(final_IP_List_Program_Output_csv):
mode = 'a'
header = 0
else :
mode ='w'
header = headers
with open(final_IP_List_Program_Output_csv,mode=mode,newline='',encoding='utf8',errors='replace') as csvfile:
content = table.to_csv(csvfile,sep=',',encoding='utf-8',index=False,line_terminator="",header=header,quoting=csv.QUOTE_NONE)
print("Successfully uploaded the csv file.")
with gzip.open(final_IP_List_Program_Output_csv_gz, 'a') as compressed_file:
compressed_file.write(table.to_csv(content,sep=',',encoding='utf-8',index=False,line_terminator="",header=header,quoting=csv.QUOTE_NONE).encode())
print("Successfully uploaded the compressed file")
except Exception as err :
print("Error Occurred during FileCreation. Kindly recheck the code.",err)
sys.exit()
This function gets called to update each line. Using the above I am first creating a csv file first and then a zipped csv file. But my zipped csv file itself is very large in size than the normal csv file.
Trail 2:
tf = tarfile.open(final_IP_List_Program_Output_csv_gz, mode="w:gz")
table = pd.DataFrame(result)
with open(final_IP_List_Program_Output_csv,mode=mode, newline='', encoding='utf8', errors='replace') as file:
table.to_csv(file,sep=',',mode=mode,encoding='utf-8',index=False ,header=header,line_terminator="",quoting=csv.QUOTE_NONE)
tf.add(final_IP_List_Program_Output_csv,arcname=os.path.basename(final_IP_List_Program_Output_csv))
tf.close()
print("Successfully uploaded the csv file.")
Using this , I am able to add only the first line to tar.gz file , but the original csv file is having more than one line.
with open(final_IP_List_Program_Output_csv,mode=mode, newline='', encoding='utf8', errors='replace') as csvfile:
table.to_csv(csvfile,sep=',',encoding='utf-8',index=False,line_terminator="",header=header,quoting=csv.QUOTE_NONE)
print("Successfully uploaded the csv file.")
tf.add(final_IP_List_Program_Output_csv,arcname=os.path.basename(final_IP_List_Program_Output_csv))
tf.close()
print("Successfully uploaded the compressed file")
The above worked.
Right now I am doing the following.
import xlrd
resp = requests.get(url, auth=auth).content
output = open(r'temp.xlsx', 'wb')
output.write(resp)
output.close()
xl = xlrd.open_workbook(r'temp.xlsx')
sh = 1
try:
for sheet in xl.sheets():
xls.append(sheet.name)
except:
xls = ['']
It's extracting the sheets but I don't know how to read the file or if saving the file as an .xlsx is actually working for macros. All I know is that the code is not working right now and I need to be able to catch the data that is being generated in a macro. Please help! Thanks.
I highly recommend using xlwings if you want to open, modify, and save .xlsm files without corrupting them. I have tried a ton of different methods (using other modules like openpyxl) and the macros always end up being corrupted.
import xlwings as xw
app = xw.App(visible=False) # IF YOU WANT EXCEL TO RUN IN BACKGROUND
xlwb = xw.Book('PATH\\TO\\FILE.xlsm')
xlws = {}
xlws['ws1'] = xlwb.sheets['Your Worksheet']
print(xlws['ws1'].range('B1').value) # get value
xlws['ws1'].range('B1').value = 'New Value' # change value
yourMacro = xlwb.macro('YourExcelMacro')
yourMacro()
xlwb.save()
xlwb.close()
Edit - I added an option to keep Excel invisible at users request
I have created a workbook using xlwt, now I was wondering if I could send an email using this workbook, but a without saving the workbook on disk. I am unable to do a proper implementation where I could send it as an attachment without saving it on disk temporarily. Here is the code for email as an attachment.
file_name = "temp_file_location.xlsx"
book = xlwt.Workbook()
sheet = book.add_sheet("XYZ")
book.save(file_name)
message = EmailMessage(subject="Subject", body="body",
from_email="random#gmail.com",
to=email_list)
message.attach_file(file_name)
message.send()
There is a similar question here:
How to send an email with attachment?
But no solution, and I am unable to send email without saving it on disk temporarily.
Any Ideas?
You can write your workbook in memory using StringIO:
import StringIO
f = StringIO.StringIO() # create a file-like object
book = xlwt.Workbook()
sheet = book.add_sheet("XYZ")
book.save(f)
message = EmailMessage(subject="Subject", body="body",
from_email="random#gmail.com",
to=email_list)
message.attach('filename.xlsx', f.getvalue(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") #get the stream and set the correct mimetype
message.send()
taken from xlwt write excel sheet on the fly