4

我正在使用GemBox.EmailGemBox.Document将电子邮件转换为 PDF。

这是我的代码:

static void Main()
{
    MailMessage message = MailMessage.Load("input.eml");
    DocumentModel document = new DocumentModel();

    if (!string.IsNullOrEmpty(message.BodyHtml))
        document.Content.LoadText(message.BodyHtml, LoadOptions.HtmlDefault);
    else
        document.Content.LoadText(message.BodyText, LoadOptions.TxtDefault);

    document.Save("output.pdf");
}

该代码适用于 EML 文件,但不适用于 MSG(MailMessage.BodyHtmlMailMessage.BodyText)为空。

我怎样才能使这个工作也适用于味精?

4

1 回答 1

4

问题发生在特定的 MSG 文件中,这些文件在 RTF 正文中没有 HTML 内容,相反,它们有原始的 RTF 正文。

该类MailMessage目前不公开 RTF 正文的 API(仅普通和 HTML 正文)。不过,您可以将其检索为Attachment名为“ Body.rtf ”。

另外作为一个仅供参考,您遇到的另一个问题是电子邮件 HTML 正文中的图像没有内联,因此,您在导出为 PDF 时会丢失它们。

无论如何,请尝试使用以下内容:

static void Main()
{
    // Load an email (or retrieve it with POP or IMAP).
    MailMessage message = MailMessage.Load("input.msg");

    // Create a new document.
    DocumentModel document = new DocumentModel();

    // Import the email's body to the document.
    LoadBody(message, document);

    // Save the document as PDF.
    document.Save("output.pdf");
}

static void LoadBody(MailMessage message, DocumentModel document)
{
    if (!string.IsNullOrEmpty(message.BodyHtml))
    {
        var htmlOptions = LoadOptions.HtmlDefault;
        // Replace attached CID images to inlined DATA urls.
        var htmlBody = ReplaceEmbeddedImages(message.BodyHtml, message.Attachments);
        // Load HTML body to the document.
        document.Content.End.LoadText(htmlBody, htmlOptions);
    }
    else if (message.Attachments.Any(a => a.FileName == "Body.rtf"))
    {
        var rtfAttachment = message.Attachments.First(a => a.FileName == "Body.rtf");
        var rtfOptions = LoadOptions.RtfDefault;
        // Get RTF body from the attachment.
        var rtfBody = rtfOptions.Encoding.GetString(rtfAttachment.Data.ToArray());
        // Load RTF body to the document.
        document.Content.End.LoadText(rtfBody, rtfOptions);
    }
    else
    {
        // Load TXT body to the document.
        document.Content.End.LoadText(message.BodyText, LoadOptions.TxtDefault);
    }
}

static string ReplaceEmbeddedImages(string htmlBody, AttachmentCollection attachments)
{
    var srcPattern =
        "(?<=<img.+?src=[\"'])" +
        "(.+?)" +
        "(?=[\"'].*?>)";

    // Iterate through the "src" attributes from HTML images in reverse order.
    foreach (var match in Regex.Matches(htmlBody, srcPattern, RegexOptions.IgnoreCase).Cast<Match>().Reverse())
    {
        var imageId = match.Value.Replace("cid:", "");
        Attachment attachment = attachments.FirstOrDefault(a => a.ContentId == imageId);

        if (attachment != null)
        {
            // Create inlined image data. E.g. "data:image/png;base64,AABBCC..."
            ContentEntity entity = attachment.MimeEntity;
            var embeddedImage = entity.Charset.GetString(entity.Content);
            var embeddedSrc = $"data:{entity.ContentType};{entity.TransferEncoding},{embeddedImage}";

            // Replace the "src" attribute with the inlined image.
            htmlBody = $"{htmlBody.Substring(0, match.Index)}{embeddedSrc}{htmlBody.Substring(match.Index + match.Length)}";
        }
    }

    return htmlBody;
}

有关更多信息(例如如何将电子邮件标题和附件添加到输出 PDF),请查看将电子邮件转换为 PDF示例。

于 2020-09-29T12:57:56.057 回答