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.
Related
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')
Formatted Excel range copied to a Word file
This copies a range of cells from Excel and pastes them into a Word document with formatting preserved. The code works for this. However, I also want to paste the data into the body of an email with the cell styles.
import sys
from pathlib import Path
import win32com.client as win32
excel_path = str(Path.cwd() / 'input.xlsx')
excel = win32.gencache.EnsureDispatch('Excel.Application')
excel.Visible = False
excel.DisplayAlerts = False
wb = excel.Workbooks.Open(excel_path)
ws = wb.Worksheets(1)
ws.Range("A1:B2").Copy()
wb.Close()
word_path = str(Path.cwd() / 'output.docx')
word = win32.gencache.EnsureDispatch('Word.Application')
doc = word.Documents.Open(word_path)
doc.Content.PasteExcelTable(False, False, True)
doc.Close()
# That works, but now I want to paste the copied Excel range into the body of
# an email. The solution may look something like the following with the "X"
# as a "Selection" or "Range" object for the PasteExcelTable method.
outlook = win32.gencache.EnsureDispatch('Outlook.Application')
new_mail = outlook.CreateItem(0)
new_mail.To = 'person#email.com'
new_mail.Body = ws.Range("A1:B2").PasteExcelTable(False, False, True)
new_mail.Send()
sys.exit()
I believe [PasteExcelTable]2 can be used to make this happen with Outlook as it does for Word files and perhaps someone knows how this can be done.
I'm not defining the range correctly. Here's an example of one of my attempts:
new_mail.Body = ws.Range("A1:B2").PasteExcelTable(False, False, True)
I know this could be accomplished with VBA, but I want to use Python and to see whether PasteExcelTable will work for this. If it is not possible, I will capture an image of the data range and paste that to the email.
After hours of research and experimentation I found out how to use PasteExcelTable in Outlook. I hope this can be helpful. You only need to have the Excel Table in the clipboard.
import win32com.client
outlook = win32com.client.Dispatch('Outlook.Application')
mail = outlook.CreateItem(0)
mail.To = "person#email.com"
mail.Subject = "Subject"
mail.Display()
inspector = outlook.ActiveInspector()
word_editor = inspector.WordEditor
word_range = word_editor.Application.ActiveDocument.Content
word_range.PasteExcelTable(False, False, True)
Hope this will help...
import win32com.client as win32
import pandas as pd
df = pd.read_excel('fullexelpath.xlsx', index_col=False, nrows = 5, usecols = "A:D")
body = df.to_html()
outlook = win32.gencache.EnsureDispatch('Outlook.Application')
mail = outlook.CreateItem(0)
mail.To = 'abc#gmail.com'
mail.HTMLBody = (body)
mail.Send()
This copies a range of cells from Excel and pastes them into a Word document with formatting preserved. The code works for this. However, I also want to paste the data into the body of an email with the cell styles.
There are three main ways for working with bodies in Outlook:
Body - a plain text representing the message body.
HTMLBody.
Word editor. Outlook uses Word as an email editor. The Inspector class provides the WordEditor property which returns an instance of the Document class from the Word object model which represents the message body. Or just use the [GetInspector] method of the MailItem class to retrieve an instance of the Inspector class. You can read more about that in the Chapter 17: Working with Item Bodies .
So, basically you can re-use the same codebase used for Word in case of Outlook.
I was unable to use PasteExcelTable, but I was able to accomplish this with HTMLBody using the following code:
import sys
from pathlib import Path
import win32com.client as win32
from PIL import ImageGrab
excel_path = str(Path.cwd() / 'input.xlsx')
excel = win32.gencache.EnsureDispatch('Excel.Application')
excel.Visible = False
excel.DisplayAlerts = False
wb = excel.Workbooks.Open(excel_path)
ws = wb.Worksheets(1)
win32c = win32.constants
ws.Range("A1:B2").CopyPicture(Format=win32c.xlBitmap)
img = ImageGrab.grabclipboard()
image_path = str(Path.cwd() / 'test.png')
img.save(image_path)
outlook = win32.gencache.EnsureDispatch('Outlook.Application')
new_mail = outlook.CreateItem(0)
new_mail.To = 'person#email.com'
new_mail.Attachments.Add(Source=image_path)
body = "<h1>Email text...</h1><br><br> <img src=test.png>"
new_mail.HTMLBody = (body)
new_mail.Send()
wb.Close()
sys.exit()
I want to open Outlook email (msg) file in read and write mode to parse it and alter date values. To fetch (read mode) date from msg file and then replace (write mode) dummy date to msg file. I did following so far.
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
msg = outlook.OpenSharedItem(r"C:\Users\abc.msg")
print msg.SentOn
I am able to get SendOn date. It means its by default in read mode. How to open it in to write mode and replace SendOn date with Dummy date. Or any other way to do so?
SentOn property is read-only in the Outlook Object Model. You'd need Extended MAPI for that (C++ or Delphi, use OpenIMsgOnIStg, set the PR_CLIENT_SUBMIT_TIME property) or Redemption (any language):
set Session = CreateObject("Redemption.RDOSession")
set Msg = Session.GetMessageFromMsgFile("C:\Users\abc.msg")
Msg.SentOn = #5/17/2016#
Msg.Save
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
I am using win32com.client in Python to send an email.
However I want the body of the email to be a table (HTML- formatted table), I can do it in an Excel first and then copy and paste (but how?), or directly edit the corresponding Pandas data frame.
newMail.body = my_table which is a Pandas data frame didn't work.
So I'm wondering if there is smarter ways for example, to combine Excel with Outlook apps within Python?
Cheers,
There are solutions regarding how to convert your Excel table to HTML here: How do I save Excel Sheet as HTML in Python?, and then you just drop the HTML into the body of your email.
Per request in the comments:
Once you have the HTML-formatted version of your table in a file called mytable.html, you can drop it into the email with: newMail.body = open("mytable.html").read()
I m replying on old quest , but it comes on the top in search,may be helpful.
import win32com.client as win32
import pandas as pd
# Read A to D column and first 5 rows
df = pd.read_excel('yourfilepath.xlsx', index_col=False, nrows = 5, usecols = "A:D")
body = df.to_html()
outlook = win32.gencache.EnsureDispatch('Outlook.Application')
new_mail = outlook.CreateItem(0)
new_mail.To = 'person#email.com'
new_mail.HTMLBody = (body)
new_mail.Send()