在 PST 文件中使用消息

向 Outlook PST 文件添加邮件

向 PST 文件添加单封邮件

创建新 PST 文件并添加子文件夹 展示了如何创建 PST 文件并向其添加子文件夹。使用 Aspose.Email,您还可以向已创建或加载的 PST 文件的子文件夹添加邮件。以下代码示例演示了如何创建新 PST 文件、添加一个 "Inbox" 文件夹,然后向该文件夹添加一封邮件。该 PersonalStorage 以及 FolderInfo 类用于执行此任务。

  1. 使用 PersonalStorage.create 方法,用于指定文件路径和 Unicode 格式版本来初始化新 PST 文件。
  2. 在 PST 文件的根目录创建名为 "Inbox" 的新文件夹。
  3. 使用以下方式将邮件添加到新创建的 "Inbox" 文件夹: add_message 方法。
  4. 使用以下方式加载邮件 MapiMessage.load.
pst = PersonalStorage.create(dataDir + "AddMessagesToPst_out.pst", FileFormatVersion.UNICODE)

# Add new folder "Inbox"
inboxFolder = pst.root_folder.add_sub_folder("Inbox");

# Add message to Inbox Folder
inboxFolder.add_message(MapiMessage.load(dataDir + "MapiMsgWithPoll.msg"))

pst.dispose()

向 PST 文件添加多封邮件以提升性能

向 PST 添加单个邮件会导致更多的磁盘 I/O 操作,从而可能降低性能。为提升性能,可以以批量模式将邮件添加到 PST,并最小化 I/O 操作。

从磁盘加载并添加邮件

add_messages 该方法允许您定义要添加到 PST 文件的邮件范围。下面的代码示例演示了如何从磁盘一次性添加多封邮件到 PST 文件以提升性能:

  1. 通过创建定义函数 add_messages_in_bulk_mode 使用 PST 文件名和包含邮件的文件夹作为参数。
  2. 使用以下方式打开指定的 PST 文件 PersonalStorage.from_file().
  3. 从 PST 根文件夹检索子文件夹 "myInbox"。
  4. 使用以下方式批量从指定文件夹添加邮件 folder.add_messages().
  5. 调用 add_messages_in_bulk_mode() 将 PST 文件和文件夹名称作为参数传入。
from aspose.email.storage.pst import PersonalStorage, StandardIpmFolder, FileFormatVersion

def add_messages_in_bulk_mode(file_name, msg_folder_name):
    with PersonalStorage.from_file(file_name) as personal_storage:
        folder = personal_storage.root_folder.get_sub_folder("myInbox")
        folder.add_messages(message_collection(msg_folder_name))

# Add multiple messages from the specified folder to the PST file for improved performance
add_messages_in_bulk_mode("file.pst", "folder_with_messages")

使用 MapiMessageEnumerator 用于批量操作

为简化批量邮件处理,您可以实现 MapiMessageEnumerator 类,可高效遍历存储在指定文件夹中的邮件。以下 Python 脚本提供了使用 Aspose.Email 库枚举和遍历 MAPI 邮件的结构化方法。它定义了两个辅助类:

  • MapiMessageEnumerator 用于从目录读取邮件,

  • MapiMessageCollection 用于在批量操作期间管理它们。

此方法有助于遍历和处理 MAPI 消息文件。

import os
from aspose.email.mapi import MapiMessage

# Define a class to enumerate through MAPI message files in a directory
class MapiMessageEnumerator:
    def __init__(self, path):
        self.files = os.listdir(path)
        self.position = -1

    def __next__(self):
        self.position += 1
        if self.position < len(self.files):
            return MapiMessage.from_file(os.path.join(self.path, self.files[self.position]))
        else:
            raise StopIteration

    def __iter__(self):
        return self

# Define a collection class for managing MAPI messages
class MapiMessageCollection:
    def __init__(self, path):
        self.path = path

    def __iter__(self):
        return MapiMessageEnumerator(self.path)


# Iterate through MAPI messages in a specific directory
msg_folder_name = "\\Files\\msg"

# Initialize a collection with the directory containing message files
message_collection = MapiMessageCollection(msg_folder_name)
for message in message_collection:
    # Process each MAPI message object as needed
    pass

从另一个 PST 添加消息

要将邮件从一个 PST 文件导入到另一个,Aspose.Email 提供了 FolderInfo.enumerate_mapi_messages() 方法。以下代码示例演示了如何将一个 PST 文件中 "Inbox" 文件夹的邮件复制到另一个 PST 文件中:

从 Outlook PST 文件检索邮件

读取 Outlook PST 文件,检索文件夹和子文件夹信息,我们讨论了加载 Outlook PST 文件并浏览其文件夹以获取文件夹名称及其中邮件数量。本文解释了如何访问和提取 Outlook PST 文件中的邮件:检索基本邮件详情、统计文件夹中项目数量,以及提取特定数量的邮件进行处理或分析。

检索基本邮件信息

以下代码示例演示了如何使用 Aspose.Email 库提取并显示存储在 PST 文件中的 MAPI 消息的关键信息。它初始化了一个 PersonalStorage 从 "Outlook.pst" 文件中获取对象,检索根文件夹的内容,并遍历每封邮件。脚本打印出主题、发件人信息、收件人地址、发送时间和邮件正文等细节,提供对指定 PST 文件中每封电子邮件的全面概览。

from aspose.email.storage.pst import *
from aspose.email.mapi import MapiMessage

pst = PersonalStorage.from_file("Outlook.pst")

folderInfo = pst.root_folder

messageInfoCollection = folderInfo.get_contents()

for messageInfo in messageInfoCollection:
   mapi = pst.extract_message(messageInfo)

   print("Subject: " + mapi.subject)
   print("Sender name: " + mapi.sender_name)
   print("Sender email address: " + mapi.sender_email_address)
   print("To: ", mapi.display_to)
   print("Cc: ", mapi.display_cc)
   print("Bcc: ", mapi.display_bcc)
   print("Delivery time: ", str(mapi.delivery_time))
   print("Body: " + mapi.body)

递归读取嵌套文件夹

Outlook PST 文件可能包含嵌套文件夹。要获取这些文件夹以及顶层文件夹的邮件信息,请使用递归方法读取所有文件夹。以下代码片段展示了如何读取 Outlook PST 文件并递归显示文件夹和邮件内容:

检索 PST 文件夹中的总项目数

要检索消息存储中项目的总数(如电子邮件、约会、任务、联系人等),请使用 get_total_items_count() 方法 MessageStore 类。它提供了一种便捷方式,可快速获取存储中数据的大小和数量信息。以下代码片段展示了如何获取 PST 文件中的项目总数:

import aspose.email as ae

pst = ae.storage.pst.PersonalStorage.from_file("my.pst")

count = pst.store.get_total_items_count()

提取特定数量的邮件

要从 PST 文件中提取指定数量的邮件,请使用 get_contents(start_index, count) 方法 FolderInfo 类。它接受两个参数:

  • start_index - 起始邮件的编号,例如第10封;
  • count - 要检索的邮件总数。

一次检索仅必要的邮件子集对于管理大量电子邮件数据很有用。以下代码示例演示了此功能的实现:

import aspose.email as ae

pst = ae.storage.pst.PersonalStorage.from_file("my.pst")

folder = pst.root_folder.get_sub_folder("Inbox")

# Extracts messages starting from 10th index top and extract total 100 messages
messages = folder.get_contents(10, 100)

在 PST 文件中处理附件

在不提取整封邮件的情况下提取附件

Aspose.Email for Python 允许从 PST 消息中提取附件,而无需先提取整封邮件。可以使用以下方式实现: extract_attachments 方法的 PersonalStorage 类。以下代码片段演示了在跳过 .msg 文件的情况下提取附件:

from aspose.email.storage.pst import PersonalStorage

# Open the PST file 
with PersonalStorage.from_file(data_dir + "my.pst") as personal_storage:
    # Get the "Inbox" subfolder from the root folder in the personal storage
    folder = personal_storage.root_folder.get_sub_folder("Inbox")

    # Iterate over each message entry ID in the Inbox folder
    for message_info in folder.enumerate_messages_entry_id():
        # Extract attachments for the current message
        attachments = personal_storage.extract_attachments(message_info)

        # Check if the message has any attachments
        if attachments.count > 0:
            # Iterate over each attachment in the list
            for attachment in attachments:
                # Ignore attachments that are message files (.msg)
                if attachment.long_file_name and attachment.long_file_name.endswith(".msg"):
                    continue
                # Save the attachment with its original file name
                attachment.save(data_dir + attachment.long_file_name)

将文件作为附件添加到 PST 邮件

Microsoft Outlook 是一款强大的电子邮件、日历、任务、联系人和日志条目管理工具。除这些核心功能外,它还允许将文件添加到 PST 文件夹,从而使用户能够完整记录相关文档。Aspose.Email 简化了向 PST 文件夹添加文件的过程,功能类似于处理邮件、联系人、任务和日志条目。

以下代码片段说明了如何使用 Aspose.Email 将文档添加到 PST 文件夹中:

from aspose.email.storage.pst import PersonalStorage, FileFormatVersion

# Create a new PST file
personal_storage = PersonalStorage.create(data_dir + "AddFilesToPst_out.pst", FileFormatVersion.UNICODE)

# Add a new folder to store files
folder = personal_storage.root_folder.add_sub_folder("Files")

# Add a file to the PST folder
folder.add_file(data_dir + "FileToBeAddedToPST.txt", "")

在 PST 文件中搜索和过滤邮件

个人存储(PST)文件可能包含大量数据,需要使用多重过滤才能找到符合特定条件的数据。使用 PersonalStorageQueryBuilder 类,Aspose.Email 使您能够基于定义的搜索条件在 PST 中搜索特定记录。您可以使用发件人、收件人、主题、邮件重要性、是否有附件、邮件大小甚至邮件 ID 等参数进行搜索。此外, PersonalStorageQueryBuilder 可用于在子文件夹中搜索。以下章节提供了关于搜索 Outlook PST 文件的综合指南。

搜索 Outlook 邮件和文件夹

下面的代码片段展示了如何使用 PersonalStorageQueryBuilder 类,用于根据不同搜索条件在 PST 中搜索内容。它特别演示了基于以下条件搜索 PST:

  • 邮件重要性。
  • 邮件类别。
  • 是否有附件。
  • 邮件大小。
  • 未读邮件。
  • 未读且带附件的邮件,以及具有特定子文件夹名称的文件夹。
from aspose.email.mapi import MapiMessageFlags
from aspose.email.storage.pst import PersonalStorage, PersonalStorageQueryBuilder, MapiImportance

with PersonalStorage.from_file(data_dir + "my.pst") as personal_storage:
    folder = personal_storage.root_folder.get_sub_folder("Inbox")
    builder = PersonalStorageQueryBuilder()

    # High importance messages
    builder.importance.equals(2)
    messages = folder.get_contents(builder.get_query())
    print("Messages with High Imp:", messages.count)

    builder = PersonalStorageQueryBuilder()
    builder.message_class.equals("IPM.Note")
    messages = folder.get_contents(builder.get_query())
    print("Messages with IPM.Note:", messages.count)

    builder = PersonalStorageQueryBuilder()
    # Messages with attachments AND high importance
    builder.importance.equals(2)
    builder.has_flags(MapiMessageFlags.HASATTACH)
    messages = folder.get_contents(builder.get_query())
    print("Messages with atts:", messages.count)

    builder = PersonalStorageQueryBuilder()
    # Messages with size > 15 KB
    builder.message_size.greater(15000)
    messages = folder.get_contents(builder.get_query())
    print("Messages size > 15 KB:", messages.count)

    builder = PersonalStorageQueryBuilder()
    # Unread messages
    builder.has_no_flags(MapiMessageFlags.READ)
    messages = folder.get_contents(builder.get_query())
    print("Unread:", messages.count)

    builder = PersonalStorageQueryBuilder()
    # Unread messages with attachments
    builder.has_no_flags(MapiMessageFlags.READ)
    builder.has_flags(MapiMessageFlags.HASATTACH)
    messages = folder.get_contents(builder.get_query())
    print("Unread msgs with atts:", messages.count)

    # Folder with name 'SubInbox'
    builder = PersonalStorageQueryBuilder()
    builder.folder_name.equals("SubInbox")
    folders = folder.get_sub_folders(builder.get_query())
    print("Folder having subfolder:", folders.count)

    builder = PersonalStorageQueryBuilder()
    # Folders with subfolders
    builder.has_subfolders()
    folders = folder.get_sub_folders(builder.get_query())
    print("Folders with subfolders:", folders.count)

使用不区分大小写的匹配进行搜索

通过利用 Aspose.Email PersonalStorageQueryBuilder,您可以指定电子邮件的搜索条件且忽略大小写,从而实现更灵活、用户友好的搜索体验。以下代码示例演示了如何加载 PST 文件、访问 "Inbox" 文件夹,并应用不区分大小写的搜索过滤器,根据发件人信息定位电子邮件。此功能在处理电子邮件数据大小写不一致时尤为有用。

使用多个关键字搜索主题行

通过实现以下方式,从个人存储文件(PST)或消息存储中检索特定消息或项目: either(query1, query2) 方法的 PersonalStorageQueryBuilder 类。它接受两个参数,允许您组合两个不同的查询 query1 和 query2,并找到其主题匹配任意一个指定词的消息。见下方代码示例:

import aspose.email as ae

builder1 = ae.storage.pst.PersonalStorageQueryBuilder()
builder1.subject.contains("Review") # 'Review' is key word for the search

builder2 = ae.storage.pst.PersonalStorageQueryBuilder()
builder2.subject.contains("Error") # 'Error' is also key word for the search

builder = ae.storage.pst.PersonalStorageQueryBuilder()
# message subjects must contain 'Review' or 'Error' words
builder.either(builder1.get_query(), builder2.get_query())


pst = ae.storage.pst.PersonalStorage.from_file("my.pst")

folder = pst.root_folder.get_sub_folder("Inbox")
messages = folder.get_contents(builder.get_query())

for message in messages:
    print(f"Message: {message.subject}")

根据特定条件过滤 PST 中的电子邮件

仅检索符合特定过滤条件的消息,例如主题、发件人或日期,使用 MailQuery 类。以下代码示例演示如何使用 Aspose.Email 库加载 PST 文件,并在特定文件夹(本例中为 “Inbox” 文件夹)中筛选消息:

import aspose.email as ae

# Load the PST file and access a folder
pst = ae.PersonalStorage.from_file("sample.pst")
inbox = pst.root_folder.get_sub_folder("Inbox")

# Create a MailQuery to filter messages by subject
query_builder = ae.MailQueryBuilder()
query_builder.subject.contains("Invoice")

query = query_builder.get_query()

# Enumerate filtered messages
for info in inbox.enumerate_mapi_messages(query):
    print("Subject:", info.subject)

按类型检索消息

Aspose.Email MessageKind 重载允许您获取特定类型的消息,例如仅电子邮件、约会或联系人。以下代码示例演示了如何从指定文件夹访问并过滤特定类型的消息:

import aspose.email as ae

# Load the PST and target folder
pst = ae.PersonalStorage.from_file("sample.pst")
inbox = pst.root_folder.get_sub_folder("Inbox")

# Retrieve only email messages (not calendar items, contacts, etc.)
for info in inbox.enumerate_mapi_messages(ae.MessageKind.MAPI_MESSAGE):
    print("Email Message:", info.subject)

对大型 PST 文件进行分页检索消息

在处理包含大量消息的文件夹时,您可以使用分页以块方式加载消息,使用 start_indexcount 参数。以下代码示例演示了如何从 PST 文件中访问并检索特定范围的电子邮件,而不是一次性获取全部:

import aspose.email as ae

# Load the PST and access the target folder
pst = ae.PersonalStorage.from_file("sample.pst")
inbox = pst.root_folder.get_sub_folder("Inbox")

# Retrieve messages from index 0 to 9
for info in inbox.enumerate_mapi_messages(0, 10):
    print("Paged Message:", info.subject)

更新并组织 Outlook PST 内容

在文件夹之间移动邮件

Aspose.Email 使得可以将项目从源文件夹移动到同一个人存储 (PST) 文件的另一个文件夹。包括:

  • 将指定的文件夹移动到新父文件夹。
  • 将指定的消息移动到新文件夹。
  • 将内容移动到新文件夹。
  • 将子文件夹移动到新父文件夹。

以下代码片段展示了如何将消息和文件夹等项目从源文件夹移动到同一 PST 文件中的另一个文件夹。

更新消息属性

有时需要修改消息的某些属性,例如更改主题、标记消息重要性等。使用以下方法可以在 PST 文件中更新这些属性: FolderInfo.change_messages Aspose.Email for Python 提供的方法。本文展示了批量更新消息属性的过程,允许在 PST 文件中对多个消息进行自动化调整。下面有一个代码片段,演示如何对各种消息属性执行批量更新。

from aspose.email.storage.pst import PersonalStorage, PersonalStorageQueryBuilder
from aspose.email.mapi import MapiPropertyTag, MapiProperty, MapiPropertyCollection

pst_file_path = data_dir + "ya4demia04vb.pst"

# Load the Outlook PST file
with PersonalStorage.from_file(pst_file_path) as personal_storage:
    # Get the required subfolder
    inbox = personal_storage.root_folder.get_sub_folder("Inbox")

    # Find messages having From = "someuser@domain.com"
    query_builder = PersonalStorageQueryBuilder()
    query_builder.from_address.contains("someuser@domain.com")

    # Get contents from query
    messages = inbox.get_contents(query_builder.get_query())

    # Save (MessageInfo, EntryIdString) in a list
    change_list = [message_info.entry_id_string for message_info in messages]

    # Compose the new properties
    updated_properties = MapiPropertyCollection()
    updated_properties.add(
        MapiPropertyTag.SUBJECT_W,
        MapiProperty(MapiPropertyTag.SUBJECT_W, "New Subject".encode("utf-16le"))
    )
    updated_properties.add(
        MapiPropertyTag.IMPORTANCE,
        MapiProperty(MapiPropertyTag.IMPORTANCE, bytearray([0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
    )

    # Update messages having From = "someuser@domain.com" with new properties
    inbox.change_messages(change_list, updated_properties)

修改自定义 MAPI 属性

有时您可能需要识别并标记在 PST 文件中已处理的项目。Aspose.Email API 提供了通过使用以下方式完成此任务的解决方案: MapiPropertyMapiNamedProperty 类。这些类使您能够通过分配自定义属性来标记已处理的项目。下面,您会找到对完成此标记过程特别有用的方法:

from uuid import UUID
from aspose.email.storage.pst import PersonalStorage
from aspose.email.mapi import MapiNamedProperty, MapiPropertyCollection
from aspose.email.mapi import MapiPropertyType, MapiProperty, MapiPropertyTag

def generate_named_property_tag(index, data_type):
    return (((0x8000 | index) << 16) | data_type) & 0x00000000FFFFFFFF

def run():
    # Load the Outlook file
    pst_file_path = data_dir + "my.pst"

    with PersonalStorage.from_file(pst_file_path) as personal_storage:
        test_folder = personal_storage.root_folder.get_sub_folder("Inbox")

        # Create the collection of message properties for adding or updating
        new_properties = MapiPropertyCollection()

        # Normal, Custom, and PidLidLogFlags named properties
        mapi_property = MapiProperty(
            MapiPropertyTag.ORG_EMAIL_ADDR_W,
            "test_address@org.com".encode("utf-16le")
        )
        named_property1 = MapiNamedProperty(
            generate_named_property_tag(0, MapiPropertyType.LONG),
            "ITEM_ID",
            UUID("00000000-0000-0000-0000-000000000000"),
            bytearray([0x7B, 0x00, 0x00, 0x00])
        )
        named_property2 = MapiNamedProperty(
            generate_named_property_tag(1, MapiPropertyType.LONG),
            0x0000870C,
            UUID("0006200A-0000-0000-C000-000000000046"),
            bytearray([0x00, 0x00, 0x00, 0x00])
        )
        new_properties.add(named_property1.tag, named_property1)
        new_properties.add(named_property2.tag, named_property2)
        new_properties.add(mapi_property.tag, mapi_property)
        test_folder.change_messages(test_folder.enumerate_messages_entry_id(), new_properties)

# Usage
run()

从 Outlook PST 文件中删除消息和文件夹

管理 Outlook PST 文件的内容通常涉及一次性删除不需要的消息、文件夹或多个项目。Aspose.Email for Python via .NET 提供了高效的方法来从 PST 文件中删除消息和文件夹,无论您是需要删除单个电子邮件, FolderInfo.delete_child_item() 方法,或执行批量删除, FolderInfo.delete_child_items() 方法,以实现更好的文件管理。

从 PST 文件中删除消息

Aspose.Email 提供了 FolderInfo 类,用于访问 PST 文件中的特定文件夹。下面的代码示例演示如何使用此类访问并删除先前加载或创建的 PST 文件的 Sent 子文件夹中的消息。具体而言,它检索消息计数并删除 “Sent Items” 文件夹中的第一项。

  1. 使用以下方法打开位于指定目录的 “Outlook.pst” 文件来初始化 PST 对象: PersonalStorage.from_file().
  2. 使用以下方式访问 Sent Items 文件夹: pst.get_predefined_folder(StandardIpmFolder.SENT_ITEMS).
  3. 然后,代码使用以下方式检索 “Sent Items” 文件夹的内容: folder.get_contents(),计数并打印此文件夹中的消息总数。
  4. 代码使用 msgsColl[0] 访问 “Sent Items” 文件夹中的第一条消息,并使用以下方式删除: folder.delete_child_item(msgInfo.entry_id)。此函数使用消息的入口 ID 将其从文件夹中移除。

删除后,代码再次计数 “Sent Items” 文件夹中的消息并打印更新后的计数。

从 PST 文件中删除项目

在许多消息系统或电子邮件客户端中,每个项目(如电子邮件、约会或任务)都会被分配一个称为入口 ID 的唯一标识符。该 delete_item(entry_id) 方法的 FolderInfo 类接受此入口 ID 作为参数,并从消息存储中移除相应项目。使用以下代码从消息存储中删除项目:

import aspose.email as ae

pst = ae.storage.pst.PersonalStorage.from_file("my.pst")

pst.delete_item(entry_id)

批量删除项目

Aspose.Email API 可用于批量删除 PST 文件中的项目。这通过使用 delete_child_items() 该方法接受一个条目 ID 项列表,指向要删除的项目。下面的代码片段展示了如何从 PST 文件中批量删除项目。

从 PST 文件中删除文件夹

Outlook PST 文件可能包含不再需要的文件夹。Aspose.Email for Python via .NET 允许您通过将这些文件夹移动到 Deleted Items 文件夹(可恢复)或永久删除它们来删除。以下示例演示了两种方法。

将文件夹移动到 Deleted Items(软删除)

move_item 方法的 PersonalStorage 该类允许文件夹以后被恢复,因为它们未被永久删除,而是移动到 Deleted Items 文件夹。下面的代码片段展示了如何在 python 项目中实现此方法:

import aspose.email as ae

pst = ae.storage.pst.PersonalStorage.from_file("my.pst")

deleted_items_folder = pst.get_predefined_folder(ae.storage.pst.StandardIpmFolder.DELETED_ITEMS)
empty_folder = pst.root_folder.get_sub_folder("Empty folder")
some_folder = pst.root_folder.get_sub_folder("Some folder")
pst.move_item(empty_folder, deleted_items_folder)
pst.move_item(some_folder, deleted_items_folder)

此方法的优势在于已删除的文件夹可以轻松恢复。

从 Deleted Items 恢复文件夹

move_item 如果文件夹被误删,此方法允许您将其从 Deleted Items 移回原位置,从而恢复文件夹。

some_folder = pst.root_folder.get_sub_folder("Some folder")
pst.move_item(some_folder, pst.root_folder)

从 Deleted Items 中永久删除文件夹

delete_child_item 如果您想立即且永久删除子文件夹,绕过 Deleted Items 文件夹,可对任何文件夹使用此方法。以下代码示例显示如何将文件夹完全从 Deleted Items 中移除,使其无法恢复:

deleted_items_folder.delete_child_item(empty_folder.entry_id)

立即永久删除文件夹

如果文件夹应在不移动到 Deleted Items 的情况下被删除, delete_child_item 方法确保立即且永久的删除。

some_folder = pst.root_folder.get_sub_folder("Some folder")
pst.root_folder.delete_child_item(some_folder.entry_id)