Create a File using xlwt and send email in Django application - python

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

Related

Edit read-only password protected excel with Python

I am trying to find a way to edit a password protected excel with Python. Password is not required to open the excel, it is only required if you want to edit it:
Is it possible to access this using password and edit it? Would be perfect if it would be possible to edit it using Openpyxl. I have already tried to use msoffcrypto:
decrypted = io.BytesIO()
with open("encrypted.xlsx", "rb") as f:
file = msoffcrypto.OfficeFile(f)
file.load_key(password="Passw0rd") # Use password
file.decrypt(decrypted)
df = pd.read_excel(decrypted)
But I think this works only when you can access the file only with password (the whole file is password encrypted, not the edit part.
If the Excel workbook has been saved with a "Password to modify" like in Office 2011 then you you usually need to perform following steps in Excel to save an unprotected version:
enter the password
open the workbook (still it is write-protected)
save as (unprotected)
In Python
You can decrypt it using a password and then pass the decrypted byte stream - as file-like object - to the opening function, be it pandas.read_excel() or openpyxl.load_workbook():
import io
import msoffcrypto
import openpyxl
decrypted_workbook = io.BytesIO()
with open('encrypted.xlsx', 'rb') as file:
office_file = msoffcrypto.OfficeFile(file)
office_file.load_key(password='passw0rd')
office_file.decrypt(decrypted_workbook)
# `filename` can also be a file-like object.
workbook = openpyxl.load_workbook(filename=decrypted_workbook)
See also:
Reading encrypted file with pandas
How to open a password protected excel file using python?
how to read password protected excel in python

How can I update an excel file in sharepoint after read?

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')

send attachment that is created in code via python

data1=[218031839]
data3=[204394266]
# dataframe Name and Age columns
df = pd.DataFrame(data1)
#Adding the header
df.set_axis(["Bans"],axis=1,inplace=True)
df.head()
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter(r'C:\user\file.xlsx', engine='xlsxwriter')
# Convert the dataframe to an XlsxWriter Excel object.
df.to_excel(writer, sheet_name='Sheet1',startrow=1,index=False)
# Close the Pandas Excel writer and output the Excel file.
writer.save()
reader = pd.read_excel(r'file.xlsx')
print(reader)
#ss_body = ss_df1.to_html(index=False)
outlook = win32.Dispatch('outlook.application')
mail = outlook.CreateItem(0)
mail.To = 'xyz#gmail.com';
'
mail.Subject = 'Report'
mail.Body = 'testing purpose now ..Pl ignore the mail'
mail.attachmensts.add(r'C:\user\file.xlsx')
mail.send()
#remove the file
Os.remove(r'C:\user\file.xlsx')
getting the below:
os.remove(r'C:\Users\file.xlsx'')
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process:
I successfully sent the mail from Python and next step is to remove the excel from the location where it is saved on my pc. But getting the above error and can anyone look into this.
You need to use the Attachments.Add method to attach a file. The source of the attachment can be a file (represented by the full file system path with a file name) or an Outlook item that constitutes the attachment. The file name is not enough. For example, the following VBA macro shows how to use the method (the Outlook object model is common for all kind of programming languages):
Sub AddAttachment()
Dim myItem As Outlook.MailItem
Dim myAttachments As Outlook.Attachments
Set myItem = Application.CreateItem(olMailItem)
Set myAttachments = myItem.Attachments
myAttachments.Add "D:\Test.xlsx", _
olByValue, 1, "Test"
myItem.Display
End Sub
Also there is no need to call the Display method right before Send.

How do I download an xlsm file and read every sheet in python?

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

Asking warning message after saving workbook in openpyxl

wb_write = openpyxl.load_workbook(file_path)
first_sheet = wb_write.get_sheet_names()[0]
ws = wb_write.get_sheet_by_name(first_sheet)
#here row=1 ,column= 5
ws.cell(row=i, column=mt_mac_id_column).value = MT_MAC
wb_write.save(file_path)
After writing data into xlsx file and saved in the same workbook.
Opened manually xlsx file in windows Changes are reflected in xlsx file but while closing the xlsx file it is asking for confirmation like "do you want to save the changes you made to file"
Why it is asking for confirmation? How do I avoid this warning?

Categories