Преобразование сообщений электронной почты в PDF-файл на C#

#c# #pdf #msg #gembox-document #gembox-email

#c# #PDF #сообщение #gembox-документ #gembox-электронная почта

Вопрос:

Я использую GemBox.Email и GemBox.Документ для преобразования электронных писем в 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.BodyHtml и MailMessage.BodyText ) пусты.

Как я могу заставить это работать и для MSG?

Комментарии:

1. MSG — это формат файла, отличный от EML и специфичный для MS Outlook. Проверьте, действительно ли GemBox может их обрабатывать. Возможно, вам нужно сообщить ему, чего ожидать.

2. Хммм, … это говорит о том, что они могут. И это определяется расширением файла. Так что ваш код должен просто работать. Можете ли вы подтвердить, что ваш .msg действительно является допустимым файлом сообщений Outlook и содержит содержимое? Можете ли вы попробовать другой файл с расширением msg? Можете ли вы открыть его в Outlook или в одном из приложений «Outlook-msg Reader»?

3. @Fildor он должен поддерживать MSG, EML и MHTML в соответствии с их примером преобразования .

4. Да, я только что прочитал это тоже. Итак, либо есть ошибка (в чем я сомневаюсь), либо ваш файл MSG каким-то образом не является допустимым файлом сообщений ms Outlook. Я бы попробовал другой файл и дважды и трижды проверил этот файл, прежде чем обращаться в службу поддержки, если вам все еще не повезло, и файл действителен.

5. @NixonUposseen Я полагаю, что проблема может быть связана с вашим файлом MSG, поэтому попробуйте предложения от Fildor. Если проблема не устранена, можете ли вы загрузить куда-нибудь свой файл MSG, чтобы я мог взглянуть на него?

Ответ №1:

Проблема возникает с определенными файлами MSG, которые не содержат HTML-содержимого в теле RTF, вместо этого у них есть необработанное тело RTF.

В MailMessage настоящее время класс не предоставляет API для тела RTF (только обычный текст и текст 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.HtmlDefau<
        // 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.RtfDefau<
        // 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.