处理附件和嵌入对象

管理电子邮件附件

电子邮件附件是与电子邮件一起发送的文件。该文件可以作为单独的消息发送,也可以作为附加到的消息的一部分发送。该 Attachment 类与一起使用 MailMessage 类。所有消息都包含正文。除了正文外,您可能想发送其他文件。这些文件作为附件发送,并表示为 Attachment 类。您可以发送任意数量的附件,但附件大小受邮件服务器限制。例如,Gmail 不支持大于 10MB 的文件。

添加附件

要向电子邮件添加附件,请按照以下步骤操作:

  1. 创建该类的实例 MailMessage 类。
  2. 创建该类的实例 Attachment 类。
  3. 将附件加载到 Attachment 实例。
  4. 添加 Attachment 实例到 MailMessage 实例。

下面的代码片段展示了如何向电子邮件添加附件。

// Create an instance of MailMessage class
MailMessage message = new MailMessage();
message.setFrom(new MailAddress("sender@from.com"));
message.getTo().add("receiver@to.com");
message.setSubject("This is message");
message.setBody("This is body");

// Load an attachment
Attachment attachment = new Attachment("1.txt");

// Add Multiple Attachment in instance of MailMessage class and Save message to disk
message.getAttachments().addItem(attachment);
message.addAttachment(new Attachment("1.jpg"));
message.addAttachment(new Attachment("1.doc"));
message.addAttachment(new Attachment("1.rar"));
message.addAttachment(new Attachment("1.pdf"));
message.save("AddAttachments.eml");

上述内容介绍了如何使用 Aspose.Email 向电子邮件添加附件。下面展示了如何删除附件并在屏幕上显示其信息。

移除附件

要移除附件,请按照以下步骤操作:

下面的代码片段展示了如何删除附件。

// Create an instance of MailMessage class
MailMessage eml = new MailMessage();
eml.setFrom(new MailAddress("sender@from.com"));
eml.getTo().add("receiver@to.com");

// Load an attachment
Attachment attachment = new Attachment("1.txt");
eml.getAttachments().addItem(attachment);

// Remove attachment from your MailMessage
eml.getAttachments().removeItem(attachment);

显示附件文件名

要显示附件文件名,请按照以下步骤操作:

  1. 遍历电子邮件中的附件并
    1. 保存每个附件。
    2. 在屏幕上显示每个附件的名称。

下面的代码片段显示了如何在屏幕上显示附件文件名。

MailMessage eml = MailMessage.load("Attachments.eml");

for (Attachment attachment : eml.getAttachments()) {
    // Display the attachment file name
    System.out.println(attachment.getName());
}

提取电子邮件附件

本主题说明如何从电子邮件文件中提取附件。电子邮件附件是随电子邮件消息一起发送的文件。该文件可以作为单独的消息发送,也可以作为其所附消息的一部分发送。所有电子邮件都提供了发送附加文件的选项。这些文件作为附件发送,并表现为 Attachment 类。该 Attachment 类与一起使用 MailMessage 类用于处理附件。要从电子邮件消息中提取附件,请按照以下步骤操作:

  • 创建该类的实例 MailMessage 类。
  • 将电子邮件文件加载到 MailMessage 实例。
  • 创建该类的实例 Attachment 类并在循环中使用它来提取所有附件。
  • 保存附件并在屏幕上显示。

|电子邮件中提取的附件| | :- | |todo:image_alt_text| 下面的代码片段展示了如何提取电子邮件附件。

MailMessage eml = MailMessage.load("Message.eml", new MsgLoadOptions());

for (Attachment attachment : eml.getAttachments()) {
    attachment.save("MessageEmbedded_out.eml");
    System.out.println(attachment.getName());
}

从附件检索 Content-Description

Aspose.Email API 提供了从附件头读取 Content-Description 的能力。下面的代码片段展示了如何从附件中检索内容描述。

MailMessage eml = MailMessage.load("EmailWithAttachEmbedded.eml");
System.out.println(eml.getAttachments().get_Item(0).getHeaders().get_Item("Content-Description"));

判断附件是否为嵌入消息

下面的代码片段演示了如何判断附件是否为嵌入的消息。

MailMessage eml = MailMessage.load("EmailWithAttachEmbedded.eml");

System.out.println(eml.getAttachments().get_Item(0).isEmbeddedMessage()
        ? "Attachment is an embedded message."
        : "Attachment isn't an embedded message.");

确定 TNEF 格式附件

Attachment.isTnef Aspose.Email Java API 的属性指示消息附件是否为 TNEF 格式的消息。

下面的代码片段演示了如何判断附件是否为 TNEF 格式:

MailMessage eml = MailMessage.load(fileName);

for (Attachment attachment : eml.getAttachments()) {
    System.out.println("Is Attachment TNEF?: " + attachment.isTnef());
}

加载和保存 TNEF 附件

Aspose.Email for Java 在 MapiAttachment 类用于执行以下操作:

从 TNEF 加载

  • static MapiAttachment loadFromTnef(String fileName) – 从 TNEF 文件中加载附件。

  • static MapiAttachment loadFromTnef(InputStream stream) – 从 TNEF 流中加载附件。

保存为 TNEF

  • void saveToTnef(String fileName) – 将附件保存到 TNEF 文件中。

  • void saveToTnef(OutputStream stream) – 将附件保存到 TNEF 流中。

下面的代码示例演示了如何从消息中提取 TNEF 附件、将其保存到流或文件,然后再将其作为 MapiAttachment:

// Load message containing a TNEF attachment (winmail.dat)
MapiMessage msg = MapiMessage.load("message.eml");

// Save the first attachment to a TNEF stream
ByteArrayOutputStream bos = new ByteArrayOutputStream();
msg.getAttachments().get(0).saveToTnef(bos);

// Load attachment back from the TNEF stream
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
MapiAttachment fromtnefAttachment = MapiAttachment.loadFromTnef(bis);
msg.getAttachments().addMapiAttachment(fromtnefAttachment);

// Load TNEF attachment directly from a file
fromtnefAttachment = MapiAttachment.loadFromTnef("winmail.dat");
msg.getAttachments().addMapiAttachment(fromtnefAttachment);

提取附件 URI(当附件为 URI-附件时)

下面的代码片段演示了如何提取附件 URI。

MailMessage eml = MailMessage.load("fileName");

Attachment attachment = eml.getAttachments().get_Item(0);
if (attachment.isUri()) {
    InputStream inputStream = attachment.getContentStream();
    String uri = new String(IOUtils.toByteArray(inputStream), Charset.forName("utf-8"));
    System.out.println("Attachment URI: " + uri);
}

添加引用附件

引用附件是本地文件附件的替代方案。在某些情况下,引用附件可能更合适,例如您希望管理其访问权限。下面的类用于管理和操作电子邮件以及其附件:

下面的代码示例演示了如何从文件加载电子邮件消息、创建具有特定属性的引用附件,并将该附件添加到电子邮件消息中:

MailMessage eml = MailMessage.load("fileName");

ReferenceAttachment refAttach = new ReferenceAttachment("https://[attach_uri]")
refAttach.setName("Document.docx");
refAttach.setProviderType(AttachmentProviderType.OneDrivePro);
refAttach.setPermissionType(AttachmentPermissionType.AnyoneCanEdit);

eml.getAttachments().addItem(refAttach);

使用嵌入对象

嵌入对象是使用一个应用程序创建并封装在另一个应用程序创建的文档或文件中的对象。例如,Microsoft Excel 电子表格可以嵌入到 Microsoft Word 报告中,或视频文件可以嵌入到 Microsoft PowerPoint 演示文稿中。当文件被嵌入而不是插入或粘贴到另一个文档中时,它会保留原始格式。嵌入的文档可以在原始应用程序中打开并进行修改。

将对象嵌入电子邮件

LinkedResource 类与一起使用 MailMessage 类用于在电子邮件中嵌入对象。要添加嵌入对象,请按照以下步骤操作

  1. 创建该类的实例 MailMessage 类。
  2. 在…中指定发件人、收件人和主题值 MailMessage 实例。
  3. 创建该类的实例 AlternateView 类。
  4. 创建该类的实例 LinkedResource 类。
  5. 将嵌入对象加载到 LinkedResourceCollection.
  6. 将加载的嵌入对象添加到 MailMessage 类实例。
  7. 添加 AlternateView 实例化到 MailMessage 类实例。

下面的代码片段生成了一封包含纯文本和 HTML 正文以及嵌入到 HTML 中的图片的电子邮件。

|嵌入到电子邮件的图片| | :- | |todo:image_alt_text| 您可以发送任意数量的嵌入对象。附件大小受邮件服务器限制。例如,Gmail 不支持大于 10MB 的文件。下面的代码片段演示了如何将对象嵌入到电子邮件中。

// Create an instance of the MailMessage class and Set the addresses and Set the content
MailMessage mail = new MailMessage();
mail.setFrom(new MailAddress("sender@from.com"));
mail.getTo().add("receiver@to.com");
mail.setSubject("This is an email");

// Create the plain text part It is viewable by those clients that don't support HTML
AlternateView plainView = AlternateView.createAlternateViewFromString("This is my plain text content", null, "text/plain");

// Create the HTML part.To embed images, we need to use the prefix 'cid' in the img src value. 
// The cid value will map to the Content-Id of a Linked resource. 
// Thus <img src='cid:barcode'> will map to a LinkedResource with a ContentId of //'barcode'.
AlternateView htmlView = AlternateView.createAlternateViewFromString("Here is an embedded image.<img src=cid:barcode>", null, "text/html");

// Create the LinkedResource (embedded image) and Add the LinkedResource to the appropriate view
LinkedResource barcode = new LinkedResource("1.jpg", MediaTypeNames.Image.JPEG);
barcode.setContentId("barcode");

mail.getLinkedResources().addItem(barcode);
mail.getAlternateViews().addItem(plainView);
mail.getAlternateViews().addItem(htmlView);
mail.save("EmbeddedImage_out.msg", SaveOptions.getDefaultMsgUnicode());

从电子邮件中移除嵌入对象

LinkedResourceCollection 通过…访问 MailMessage.LinkedResources 属性的重载版本。 LinkedResourceCollection 集合提供了一种方法来完全移除添加到电子邮件消息中的嵌入对象。请使用 LinkedResourceCollection.removeAt 用于从电子邮件消息中完全移除嵌入对象的所有痕迹的方法。

下面的示例代码展示了如何从电子邮件消息中移除嵌入对象。

// Load the test message with Linked Resources
MailMessage msg = MailMessage.load("EmlWithLinkedResources.eml");

// Remove a LinkedResource
msg.getLinkedResources().removeAt(0, true);

// Now clear the Alternate View for linked Resources
msg.getAlternateViews().get_Item(0).getLinkedResources().clear(true);

提取嵌入对象

本主题说明如何从电子邮件文件中提取嵌入对象。嵌入对象是使用一个应用程序创建并嵌入到另一个应用程序创建的文档或文件中的对象。例如,Microsoft Excel 电子表格可以嵌入到 Microsoft Word 报告中,或视频文件可以嵌入到 Microsoft PowerPoint 演示文稿中。当文件被嵌入而不是插入或粘贴到另一个文档中时,它会保留原始格式。嵌入的文档可以在原始应用程序中打开并进行修改。要从电子邮件消息中提取嵌入对象,请按照以下步骤操作:

  1. 创建该类的实例 MailMessage 类。
  2. 在…中加载电子邮件文件。 MailMessage 实例。
  3. 创建循环并创建…的实例。 Attachment 其中的类。
  4. 保存附件并在屏幕上显示。
  5. 在…中指定发件人和收件人地址 MailMessage 实例。
  6. 使用以下方式发送电子邮件 SmtpClient 类。

下面的代码片段从电子邮件中提取嵌入对象。

|邮件中提取的嵌入对象| | :- | |todo:image_alt_text| 以下代码片段展示了如何提取嵌入对象。

MailMessage mailMsg = MailMessage.load("Message.msg", new MsgLoadOptions());

for (Attachment attachment : mailMsg.getAttachments()) {
    attachment.save("MessageEmbedded_out.msg");
    System.out.println(attachment.getName());
}

识别并提取 RTF 格式 MSG 中的嵌入式附件

以下代码可用于 RTF 格式的消息,以区分并提取内联或在消息正文中显示为图标的附件。以下代码片段展示了如何识别并提取 RTF 格式 MSG 中的嵌入式附件。

public static void extractInlineAttachments() {
    MapiMessage message = MapiMessage.load("MSG file with RTF Formatting.msg");
    for (MapiAttachment attachment : message.getAttachments()) {

        if (isAttachmentInline(attachment)) {
            try {
                saveAttachment(attachment, UUID.randomUUID().toString());
            } catch (Exception ex) {
                System.err.println(ex);
            }
        }
    }
}

static boolean isAttachmentInline(MapiAttachment attachment) {
    for (MapiProperty property : attachment.getObjectData().getProperties().get_Values()) {
        if ("\u0003ObjInfo".equals(property.getName())) {
            byte[] data = property.getData();
            int odtPersist1 = data[1] << 8 | data[0];
            return (odtPersist1 & 0x40) == 0;
        }
    }
    return false;
}

static void saveAttachment(MapiAttachment attachment, String fileName) throws IOException {
    for (MapiProperty property : attachment.getObjectData().getProperties().get_Values()) {
        if ("Package".equals(property.getName())) {
            try (FileOutputStream fs = new FileOutputStream(fileName)) {
                fs.write(property.getData(), 0, property.getData().length);
            }
        }
    }
}

从已签名邮件中检索附件

已签名的邮件包含单个 smime.p7m 附件。这意味着邮件已通过 SMIME 加密。smime.p7m 文件格式是数字签名。要查看此邮件的内容,请使用 RemoveSignature 方法。该方法返回一个 MailMessage 对象未带数字签名。

MailMessage signedEml = MailMessage.load("signed.eml");

if (signedEml.isSigned()) {
    for (int i = 0; i < signedEml.getAttachments().size(); i++) {
        System.out.println("Signed email attachment" + i + ": " + signedEml.getAttachments().get_Item(i).getName());
    }

    // The email is signed. Remove a signature.
    MailMessage eml = signedEml.removeSignature();

    System.out.println("Signature removed.");

    for (int i = 0; i < eml.getAttachments().size(); i++) {
        System.out.println("Email attachment" + i + ": " + eml.getAttachments().get_Item(i).getName());
    }
}

使用 Content-Type 和 Content-Disposition

Aspose.Email API 提供了处理附件的功能 Content-TypeContent-Disposition 来自附件标题。以下代码片段展示了如何获取并更改附件的内容描述。

显示 Content-Type 和 Content-Disposition 参数

以下代码片段展示了如何在屏幕上显示 Content-Type 和 Content-Disposition 参数:

void run(MailMessage message) {
    // Attachments
    for (Attachment attachment : message.getAttachments()) {
        ContentDisposition contentDisposition = attachment.getContentDisposition();
        printContentDisposition(contentDisposition);
        ContentType contentType = attachment.getContentType();
        printContentType(contentType);
    }
    // Linked Resources
    for (LinkedResource attachment : message.getLinkedResources()) {
        ContentDisposition contentDisposition = attachment.getContentDisposition();
        printContentDisposition(contentDisposition);
        ContentType contentType = attachment.getContentType();
        printContentType(contentType);
    }
}

void printContentType(ContentType contentType) {
    System.out.println("media-type: " + contentType.getMediaType());
    System.out.println("charset: " + contentType.getCharSet());
    System.out.println("name: " + contentType.getName());
}

void printContentDisposition(ContentDisposition contentDisposition) {
    System.out.println("disposition-type: " + contentDisposition.getDispositionType());
    System.out.println("is-inline: " + contentDisposition.getInline());
    System.out.println("filename: " + contentDisposition.getFileName());
    System.out.println("creation-date: " + contentDisposition.getCreationDate());
    System.out.println("modification-date: " + contentDisposition.getModificationDate());
    System.out.println("read-date: " + contentDisposition.getReadDate());
    System.out.println("size: " + contentDisposition.getSize());
}

在附件中使用 Content-Type 和 Content-Disposition 参数

以下代码片段展示了如何在附件中使用 Content-Type 和 Content-Disposition 参数:

MailMessage eml = MailMessage.load(fileName);

Attachment attachment = new Attachment(pdfFileName, new ContentType("application/octet-stream"));
attachment.getContentDisposition().setDispositionType("attachment");
attachment.getContentDisposition().setFileName(fileName);

eml.addAttachment(attachment);