I've broken down the code for clarification.
The email template information is stored in the SysEmailTable and SysEmailMessageTable. The code below recognises the template based on the template id and saves the email subject and body as a string.
SysEmailTable sysEmailTable = SysEmailTable::find('MyTemplate');
SysEmailMessageTable sysEmailMessageTable = SysEmailMessageTable::find(sysEmailTable.EmailId, sysEmailTable.DefaultLanguage);
str messageBody = sysEmailMessageTable.Mail;
str subject = sysEmailMessageTable.Subject;
Map placeholderMap = new Map(Types::String, Types::String);
placeholderMap.insert("UserName", "Evaldas Landauskas");
messageBody = SysEmailMessage::stringExpand(messageBody, placeholderMap);
subject = SysEmailMessage::stringExpand(subject, placeholderMap);
Once you have the email subject and message, insert them into the 'SysOutgoingEmailTable' and 'SysOutgoingEmailData' table like shown below.
Records inserted in the sysoutgoingemailtable are proccessed automatically in batch.
SysOutgoingEmailTable outgoingEmailTable;
SysOutgoingEmailData outgoingEmailData;
outgoingEmailTable.EmailItemId = EventInbox::nextEventId();
outgoingEmailTable.TemplateId = sysEmailTable.EmailId;
outgoingEmailTable.Sender = sysEmailTable.SenderAddr;
outgoingEmailTable.SenderName = sysEmailTable.SenderName;
outgoingEmailTable.Recipient = 'receiver@test.com'; //To email address
outgoingEmailTable.Subject = subject;
outgoingEmailTable.Message = messageBody;
outgoingEmailTable.Priority = sysEmailTable.Priority;
outgoingEmailTable.WithRetries = true;
outgoingEmailTable.RetryNum = 0;
outgoingEmailTable.UserId = curuserid();
outgoingEmailTable.Status = SysEmailStatus::Unsent;
outgoingEmailTable.LatestStatusChangeDateTime = DateTimeUtil::getSystemDateTime();
outgoingEmailTable.insert();