Blog

All Blog Posts  |  Next Post  |  Previous Post

Formatted emails (HTML email) from TAdvRichEditor

Bookmarks: 

Tuesday, September 12, 2017

Our TAdvRichEditor UI control has everything on-board to generate HTML from its rich document content, including exporting images that are possibly used in the document. Although generating this HTML can be easily done via the TAdvRichEditorHTMLIO non-visual component connected to the TAdvRichEditor, we frequently receive support emails from users struggling to use the generated HTML to send it as email with the Indy components (TIdMessage, TidSMPT).

Therefore, we decided not only to create a sample code snippet to show how this can be done, but also to create a non-visual component (available in the latest TMS Component Pack release) to reduce the code to generate such email message to the minimum possible, that is, to one line of code:
    emailio.GenerateEmail(idmessage);

But, back to full code first that shows how to use the Indy components to generate HTML emails with embedded images as this can be generally applied for cases also where no TAdvRichEditor is used.

Drop a TIdMessage component on the form. We create a multipart message, with a part for the plain text version of the email, a part for the HTML email header and a part for the HTML itself. Then we add attachments to the message where ContentDisposition is set to 'inline' and the ContentID is set to the ID used in the HTML image reference cid attribute. So, if we have in the HTML code an image reference like:
TMS Software Delphi  Components 

then the ContentID for the attachment containing the image will be :
ContentID := 'imageref1';

Now, let's put this together using a TAdvRichEditor, TAdvRichEditorHTMLIO, idMessage on the form. We set AdvRichEditorHTMLIO.RichEditor to the TAdvRichEditor instance we want to export. It is very important to set AdvRichEditor.HTMLImages to igID as this instructs the TAdvRichEditor to export images references as CID URI attributes. The export to HTML and image files from TAdvRichEditor becomes:
var
  i: integer;
begin
  AdvRichEditor1.HTMLImages := igID;
  // we save the output to a temporary HTML file
  AdvRichEditorHTMLIO1.Save('richeditor.html');

  for i := 0 to AdvRichEditor1.HTMLImageList.Count - 1 do
    begin
      // we prepare the images as temporary images files for use as attachments for the message
      AdvRichEditor1.HTMLImageList.Items[i].SaveToFile('.img'+i.ToString+'.png');
    end;
end;

As you can see, the images to be used in the export are available via the collection AdvRichEditor.HTMLImageList. From there, we can save the images to file to be used as attachments for the Indy idMessage. The code to construct the idMessage from here becomes:
  idMessage1.IsEncoded := True ;
  idMessage1.ContentType := 'multipart/alternative';
  idMessage1.ClearBody;

  with TIdText.Create(idMessage1.MessageParts, nil) do
  begin
    // here we include the text as plain text
    Body.Text := AdvRichEditor1.PlainText;
    ContentType := 'text/plain';
    CharSet := 'UTF-8';
  end;

  with TIdText.Create(idMessage1.MessageParts, nil) do
  begin
    ContentType := 'multipart/related; type="text/html"';
  end;

  with TIdText.Create(idMessage1.MessageParts, nil) do
  begin
    // we load the content from the temporary HTML file
    Body.LoadFromFile('.
icheditor.html');
    ContentType := 'text/html';
    CharSet := 'UTF-8';
    ParentPart := 1;
  end;

  // here we loop over images to add all as attachments 
  for i := 0 to FRichEditor.HTMLImageList.Count - 1 do
  begin
    with TIdAttachmentFile.Create(idMessage1.MessageParts,  + '.img' + i.ToString + '.png') do
    begin
      ContentID := 'image'+ i.ToString;
      ContentType := 'image/png';
      ContentDisposition := 'inline';
      ParentPart := 1;
    end;
  end;

When the idMessage message has been created, it is straightforward to send it via the idSMTP component, i.e., this is minimally:
  IdMessage1.From.Address := 'info@tmssoftware.com';
  IdMessage1.Recipients.Add.Address := 'bruno@tmssoftware.com';
  IdMessage1.Sender.Address := 'info@tmssoftware.com';

  idsmtp1.Host := 'smtp.mailserver.com';
  IdSMTP1.Connect;
  idsmtp1.Send(idMessage1);
  idsmtp1.Disconnect();

With this code now explained, let's introduce the class TAdvRichEditorEmailIO included in unit AdvRichEditorEMailIO.pas in the latest version 8.7.3.0 of TMS Component Pack. With this class, we can reduce the code to send a HTML email from TAdvRichEditor to:
  AdvRichEditorEMailIO.GenerateEmail(idmessage);
  idMessage.Subject := 'A HTML email from TAdvRichEditor';

  idSMTP1.Host := 'smtp.mailserver.com';
  IdSMTP1.Connect;
  idSMTP1.Send(idMessage);
  idSMTP1.Disconnect();

The resulting Delphi application looks like this:
TMS Software Delphi  Components
and when opening the email sent in MS Outlook, it looks like:
TMS Software Delphi  Components
You can easily get started to build your own HTML formatted text email client. In the next updates of TMS FMX UI Pack that also includes the FireMonkey version of our rich editor component, we'll also include a FireMonkey version of the HTML email creator class and the same applies for the cross-framework version of the rich editor in the TMS FNC UI Pack.

Bruno Fierens


Bookmarks: 

This blog post has received 9 comments.


1. Tuesday, September 12, 2017 at 8:40:25 PM

FYI, I have a blog article on the Indy website explaining how to create HTML emails with TIdMessage, including with embedded images:

http://www.indyproject.org/Sockets/Blogs/RLebeau/2005_08_17_A.asp

Also, Indy has a TIdMessageBuilderHtml class for populating a TIdMessage with content and attachments related to HTML emails:

http://www.indyproject.org/Sockets/Blogs/RLebeau/20080116.EN.aspx

Remy Lebeau


2. Tuesday, September 12, 2017 at 9:14:30 PM

As we''re loving your FNC cross-platform framework (which makes life SO MUCH EASIER supporting multiple OS with easy/appropriate choice of FMX, VCL or LCL as each project necessitates), it would be great to see your FNC concept extended to Web apps by embracing/supporting/integrating a "render as HTML/CSS/JavaScript (or TypeScript)" like IntraWeb and UniGUI do. Or am I just dreaming?

Ralston James


3. Tuesday, September 12, 2017 at 9:17:20 PM

Everything starts with a dream.

Bruno Fierens


4. Wednesday, September 13, 2017 at 2:52:53 PM

The Class TAdvRichEditorEmailIO is not registrated!
Is this correct? Must it created at Runtime?

Klaus Holtorf


5. Wednesday, September 13, 2017 at 3:00:35 PM

By design, we don''t want to add Indy dependency in our TMS Component Pack packages.

Bruno Fierens


6. Tuesday, November 14, 2017 at 3:44:02 PM

Ok, but how I can create a multipart/mixed email.
For exemple with attachment

Agata Müller


7. Tuesday, November 14, 2017 at 5:33:07 PM

As you can see in the sample code, it already creates & uses attachment files, see code line:

TIdAttachmentFile.Create(idMessage1.MessageParts, + ''.img'' + i.ToString + ''.png'')

Bruno Fierens


8. Tuesday, November 20, 2018 at 7:41:55 PM

How can I encode text from AdvRichEditor.
After receive e-mails, I can''t see any polish national characters (only ????).


Tadeusz Marek


9. Wednesday, November 21, 2018 at 11:32:02 AM

I retested this here but could not see question marks in the email received. Could you please contact our support via email with more information how this can be reproduced?

Bruno Fierens




Add a new comment

You will receive a confirmation mail with a link to validate your comment, please use a valid email address.
All fields are required.



All Blog Posts  |  Next Post  |  Previous Post