1

I want to send arabic email using python through win32com, but I want to change the direction of text to be from Right to left in the outlook like in the picture right to left direction in outlook

Is there a way to do that through the code ?

here is my code

    import win32com.client as win32
    from pathlib import Path

    dataframe1 = dataframe.active
    olapp = win32.Dispatch('Outlook.Application')
    olns = olapp.GetNameSpace('MAPI')

    arabic_msg_file = Path('arabic_body.txt')

    mail_item = olapp.CreateItem(0)
    mail_item.CC = 'sender@gamil.com'
    mail_item.To = 'receiver@gamil.com'

    mail_item.BodyFormat = 1
    mail_item.Subject = 'subject'
    mail_item.Body = arabic_msg_file.read_text(encoding='utf-8')
    mail_item.Send()
Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • @СергейКох this the whole code, simply I want to change the direction to be from right to left instead being left to right, I think It is very clear – Abdallah Eldesouky Jan 31 '23 at 16:34
  • I am not totally sure how this differs from "right justifying" the text? Do you want the text to read from right->left in the email when it arrives at the recipient? The first issue may be that your have set `BodyFormat=1`, which is plain text. I don't think that mode has the concept of left or right justification. You may need HTML or Rich Text? – DS_London Jan 31 '23 at 17:40
  • @DS_London I want as you said to make the email read form right to left at the recipient – Abdallah Eldesouky Jan 31 '23 at 18:01
  • @DS_London If you try to send outlook email using the application or the website, you will have the ability to change the direction of text, so what I want is to control that in the code – Abdallah Eldesouky Jan 31 '23 at 18:03
  • @AbdallahEldesouky If I send an email as Plain Text, the direction is lost in the received mail. I can format R->L in the editor and the text displays that way, but that information is lost before it arrives at the other end. You may need to display the email first (with either a RTF or HTML format), and then use the WordEditor to format the paragraph. This link may be a starting point: https://learn.microsoft.com/en-us/office/vba/api/outlook.mailitem.getinspector?source=recommendations – DS_London Jan 31 '23 at 18:24

2 Answers2

1

To expand on what I suggested in the comments, here is one possible solution. I've replaced the reading of the text file with some dummy text lines.

import win32com.client as wc

ol = wc.gencache.EnsureDispatch('Outlook.Application')

text = 'Broad is the Gate and wide the Path\n' 
text += 'That leads man to his daily bath.\n'
text += 'But \'ere you spend the shining hour,\n'
text += 'With plunge and spray, with sluice and shower,\n'
text += 'Remember, whereso\'er you be,\n'
text += 'To shut the door and turn the key!\n'

item = ol.CreateItem(wc.constants.olMailItem)#=0

item.To = 'xxx@yyy.com'
item.Subject = 'Test email formatting'
item.Body = text
item.BodyFormat = wc.constants.olFormatHTML #=2

item.Display()

#Either explicitly cast to the Word Document interface
doc = wc.CastTo(item.GetInspector.WordEditor,'_Document')
doc.Paragraphs.ReadingOrder = wc.constants.wdReadingOrderRtl #=0

#Or use the 'magic number' for the reading order
#doc = item.GetInspector.WordEditor
#doc.Paragraphs.ReadingOrder = 0

item.Send()

This is what arrives at the Recipient's end:

enter image description here

Notes:

  1. I haven't found a way to be able to Send without Display-ing first. Maybe some other SO member can suggest a way? Send() throws a The parameter is incorrect exception if Display() has not been called previously.
  2. I am not a fan of 'magic numbers' replacing constants, hence I have used the gencache route for creating objects, and CastTo to generate the constants for the Word Document interface. If you want to stick with simple Dispatch() then I have included the magic numbers for the constants. Using the constants makes it easier to port VBA code to Python.

But an alternative and simpler approach is to turn the text into HTML first:

import win32com.client as wc

ol = wc.gencache.EnsureDispatch('Outlook.Application')

text = 'Broad is the Gate and wide the Path\n' 
text += 'That leads man to his daily bath.\n'
text += 'But \'ere you spend the shining hour,\n'
text += 'With plunge and spray, with sluice and shower,\n'
text += 'Remember, whereso\'er you be,\n'
text += 'To shut the door and turn the key!\n'
   
item = ol.CreateItem(wc.constants.olMailItem)#=0

item.To = 'xxx@yyy.com'
item.Subject = 'Test email formatting'

item.BodyFormat = wc.constants.olFormatHTML #=1
item.HTMLBody = "<p dir=RTL style='text-align:right;direction:rtl'><span dir=LTR>" + text.replace('\n','<br>') + "</span></p>"
   
item.Send()

I am not familiar with how punctuation works in Arabic script, so you may need to play around with the HTML markup.

DS_London
  • 3,644
  • 1
  • 7
  • 24
0

The plain text body format doesn't allow setting up any formatting, nor provides any options for specifying the layout:

mail_item.BodyFormat = 1
mail_item.Body = arabic_msg_file.read_text(encoding='utf-8')

Note, you can use the Word object model for setting up the message body in the way you need. The WordEditor property of the Inspector class returns an instance of the Word Document class where you can set up the ParagraphFormat.Alignment property, for example:

Selection.ParagraphFormat.Alignment = wdAlignParagraphRight
Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45