Search code examples
pythonexceloutlookio

Save Outlook attachment to memory instead of disk


I have a couple hundred daily Excel attachments in email that I want to pull appropriate data from and save into a database. I want to avoid saving each attachment to disk only to re-open from disk to read, since I'll never need the files saved to disk ever again. For this project, sure, I could just do it and delete them, but there ought to be a better way.

Here's what I'm doing so far

outlook = Dispatch("Outlook.Application").GetNamespace("MAPI")
folder = outlook.Folders[blah].Folders[blahblah]

for item in folder.items:
    for att in item.Attachments:
        att.SaveAsFile(???) # This is where I need something cool, like stream or bytes or something that I don't understand
        # do something with the file, either read with pandas or openpyxl

If I can get around even doing the save and have pandas / openpyxl read it without saving, that would be great, but neither of them can read the att directly.


Solution

  • Outlook Object Model won't let you do that: Attachment.SaveAsFile only allows to specify a valid file name.

    On the Extended MAPI level (C++ or Delphi only), the one and only way to access attachment data (Extended MAPI does not know anything about files) is to open the PR_ATTACH_DATA_BIN MAPI property as IStream interface: IAttach::OpenProperty(PR_ATTACH_DATA_BIN, IID_IStream, ...). You can then retreive the data directly from the IStream interface.

    If using Redemption (any language, I am its author) is an option, it exposes RDOAttachment.AsStream / AsArray / AsText properties that allow to access raw attachment data without saving it as file first.