Read the message’s RtfBody and pass it to RtfHtmlConverter.Convert: you get HTML and plain text, with no Word or Outlook. Many Outlook messages, notes and tasks carry only an RTF body. For those, the read view already does this, and HtmlBody.Origin says RtfConverted. The program below converts the RTF bodies of two Apache POI test messages: one written as RTF, and one in Cyrillic (code page 1251) that has only text and RTF.
dotnet new console -o RtfToHtml && cd RtfToHtml dotnet add package RecursiveAI.OneMail --version 0.3.0-preview.2 curl -LO https://raw.githubusercontent.com/apache/poi/REL_5_4_1/test-data/hsmf/quick.msg curl -LO https://raw.githubusercontent.com/apache/poi/REL_5_4_1/test-data/hsmf/cyrillic_message.msg
Put this in Program.cs and run dotnet run:
using RecursiveAI.OneMail; using RecursiveAI.OneMail.Rtf; foreach (string path in new[] { "quick.msg", "cyrillic_message.msg" }) { using MailContainer file = Mail.Open(path); IMailItem msg = file.Enumerate().First(); Console.WriteLine($"{path}: HTML body {msg.HtmlBody?.Origin.ToString() ?? "none"}"); if (msg.RtfBody is null) continue; // RtfBody is the decompressed RTF; the converter never throws on bad input using var rtf = new MemoryStream(); using (Stream s = msg.RtfBody.Open()) s.CopyTo(rtf); RtfHtmlResult result = RtfHtmlConverter.Convert(rtf.ToArray()); string html = Path.ChangeExtension(path, ".html"); File.WriteAllText(html, result.Html); Console.WriteLine($" {html}: {result.Html.Length:N0} characters, code page {result.DefaultCodePage}, {result.Defects.Count} defects"); Console.WriteLine($" {result.Text.Split('\n')[0].Trim()}"); }
quick.msg: HTML body RtfConverted quick.html: 173 characters, code page 1252, 0 defects The quick brown fox jumps over the lazy dog cyrillic_message.msg: HTML body none cyrillic_message.html: 874 characters, code page 1251, 0 defects Ваше сообщение с темой "FW: RTM" было успешно получено брокером подсистемы обмена данными.
cyrillic_message.html holds the automatic reply, decoded from code page 1251:
<div class="rtf-body" style="font-family:'Arial',sans-serif;font-size:10pt"> <p style="margin-top:0;margin-bottom:0">Ваше сообщение с темой "FW: RTM" было успешно получено брокером подсистемы обмена данными.</p> <p style="margin-top:0;margin-bottom:0"> В нем были обнаружены следующие вложения:</p> <p style="margin-top:0;margin-bottom:0">10595000.58B</p> <p style="margin-top:0;margin-bottom:0">10595000.56B</p> <p style="margin-top:0;margin-bottom:0">10595000.59B</p> <p style="margin-top:0;margin-bottom:0">10595000.57B</p> <p style="margin-top:0;margin-bottom:0"><br></p> <p style="margin-top:0;margin-bottom:0">Сообщение передано в обработку 18.05.2010 11:38:39</p> <p style="margin-top:0;margin-bottom:0">------------</p> <p style="margin-top:0;margin-bottom:0"> Сообщение сгенерировано автоматически, не следует отвечать на него.</p> </div>
What converts
Paragraphs, headings from the stylesheet, bold, italic and the other run styles, fonts and colours, bulleted and numbered lists, tables, hyperlinks and pictures. Pictures become data: URIs by default; set new RtfHtmlOptions { ImageMode = RtfImageMode.ContentId } to get cid: links and the bytes in result.Images. result.Text is the same document as plain text. The output is one <div class="rtf-body"> fragment, and the same input always gives the same HTML.
The project compared the converter with LibreOffice, pandoc and unrtf on 123 documents, by words, styles, lists, tables, links and headings, with no unexplained difference.
Limits
- A preview. 0.3.0-preview.2: the API can change before 1.0.
- Not sanitised. The HTML comes from the sender’s RTF. Treat it like any HTML from an email before you show it in a browser. OneMail’s display sanitiser (
ToDisplayHtml) has not had its independent security review yet: don’t rely on it to make untrusted mail safe. - Placeholders. EMF and WMF pictures and the positions of attachments inside the RTF (
\objattph) become placeholders. - Limits on size. Group depth, node count, output length and picture sizes are capped (
RtfHtmlOptions); a hit is a typed defect, and the output so far is kept.
How the converter works, and how it was checked: Compressed RTF and RTF to HTML. Reading the rest of the message: Read an Outlook MSG file.