Monday, August 4, 2025

How to Convert Outlook MSG Files to XML with a Simple Web App

 Outlook MSG files are commonly used to store individual email messages, including metadata, body content, and attachments. However, working with MSG files directly can be challenging when you need to integrate or process email data in other systems.

In this guide, we will build a Python-based web application that allows users to:
Upload Outlook MSG files
Convert them into structured XML format
Download the XML file
✔ With a clean HTML interface


✅ Why Convert MSG to XML?

  • Data Interoperability: XML is widely supported for system integrations.

  • Structured Format: Easily extract sender, recipients, body, and attachments in a standard schema.

  • Automation: Helps migrate email content into other tools like CRMs, ERP systems, or custom applications.


✅ Tools and Libraries Used

  • Python 3.x

  • Flask – lightweight web framework

  • extract-msg – library to read .msg files

  • HTML + CSS – for a simple and responsive UI

Install the dependencies:
pip install flask extract-msg

✅ Project Structure
msg-to-xml/
├── app.py              # Flask backend
├── templates/
│    └── index.html     # Upload & download UI
└── uploads/            # Temporary storage


✅ Step 1: Build the Backend (Flask)

Here’s the complete app.py code:


from flask import Flask, render_template, request, send_file

import os

import xml.etree.ElementTree as ET

import extract_msg


app = Flask(__name__)

UPLOAD_FOLDER = 'uploads'

os.makedirs(UPLOAD_FOLDER, exist_ok=True)


@app.route('/', methods=['GET', 'POST'])

def index():

    if request.method == 'POST':

        if 'file' not in request.files:

            return "No file part"

        file = request.files['file']

        if file.filename == '':

            return "No selected file"

        if file:

            file_path = os.path.join(UPLOAD_FOLDER, file.filename)

            file.save(file_path)


            # Convert MSG to XML

            xml_path = convert_msg_to_xml(file_path)

            return send_file(xml_path, as_attachment=True)

    return render_template('index.html')


def convert_msg_to_xml(msg_path):

    msg = extract_msg.Message(msg_path)


    root = ET.Element("Email")

    ET.SubElement(root, "Subject").text = msg.subject or ''

    ET.SubElement(root, "Sender").text = msg.sender or ''

    ET.SubElement(root, "Date").text = str(msg.date) if msg.date else ''

    ET.SubElement(root, "Body").text = msg.body or ''


    # Recipients

    recipients = ET.SubElement(root, "Recipients")

    for r in msg.recipients:

        try:

            recipient_text = f"{r.name} <{r.email}>"

        except:

            recipient_text = str(r)

        ET.SubElement(recipients, "Recipient").text = recipient_text


    # Attachments metadata

    attachments = ET.SubElement(root, "Attachments")

    for att in msg.attachments:

        att_elem = ET.SubElement(attachments, "Attachment")

        ET.SubElement(att_elem, "Filename").text = att.longFilename or att.shortFilename or ''

        ET.SubElement(att_elem, "Size").text = str(len(att.data)) if att.data else '0'


    tree = ET.ElementTree(root)

    xml_filename = os.path.splitext(os.path.basename(msg_path))[0] + ".xml"

    xml_path = os.path.join(UPLOAD_FOLDER, xml_filename)

    tree.write(xml_path, encoding="utf-8", xml_declaration=True)

    return xml_path


if __name__ == '__main__':

    app.run(debug=True)



✅ Step 2: Create the HTML UI

Save this as templates/index.html:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>MSG to XML Converter</title>

<style>

    body { font-family: Arial, sans-serif; background: #f4f6f9; display: flex; justify-content: center; align-items: center; height: 100vh; }

    .container { background: #fff; padding: 30px; border-radius: 12px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); text-align: center; width: 400px; }

    h1 { color: #333; margin-bottom: 20px; }

    input[type="file"] { display: block; margin: 20px auto; }

    button { background: #007BFF; color: white; border: none; padding: 10px 20px; border-radius: 8px; cursor: pointer; font-size: 16px; }

    button:hover { background: #0056b3; }

</style>

</head>

<body>

<div class="container">

    <h1>MSG to XML Converter</h1>

    <form method="POST" enctype="multipart/form-data">

        <input type="file" name="file" accept=".msg" required>

        <button type="submit">Convert & Download XML</button>

    </form>

</div>

</body>

</html>


✅ Step 3: Run the App
python app.py


Open your browser and go to:
👉 http://127.0.0.1:5000

✅ Output Example

The generated XML file will look like this:


<?xml version="1.0" encoding="utf-8"?>

<Email>

    <Subject>Test Email</Subject>

    <Sender>sender@example.com</Sender>

    <Date>2025-07-23 12:30:00</Date>

    <Body>Hello, this is a test email.</Body>

    <Recipients>

        <Recipient>John Doe &lt;john@example.com&gt;</Recipient>

    </Recipients>

    <Attachments>

        <Attachment>

            <Filename>document.pdf</Filename>

            <Size>12345</Size>

        </Attachment>

    </Attachments>

</Email>


✅ Next Enhancements

You can add more features:

  • Include attachments in Base64 inside XML

  • HTML preview before downloading

  • Support multiple file upload and batch conversion

  • Add a progress bar with drag & drop upload

✔ Final Thoughts

This lightweight Flask app is a simple and efficient way to transform Outlook MSG files into XML, making email data more accessible for integration and analysis.

No comments:

Post a Comment

How to Deploy Your HTML Website on a Linux Server (Apache + SFTP)

Launching a simple HTML website on your own Linux server is easier than you might think. Whether you're sharing a static landing page or...