You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中免费将.eml转.msg时遭遇NotOLE2FileException问题求助

EML转MSG报错解决(Java免费实现)

问题背景

需调用API传入.msg文件,本地仅有.eml文件,尝试转换时触发错误:

org.apache.poi.poifs.filesystem.NotOLE2FileException: Invalid header signature; read 0x6465766965636552, expected 0xE11AB1A1E011CFD0 - Your file appears not to be a valid OLE2 document

使用的错误代码片段:

String msg_file_path="C:\temp\msg_email.msg";
FileOutputStream msg_file = new FileOutputStream(msg_file_path);
try {
MAPIMessage msgObj = new MAPIMessage("C:\temp\_emai.eml");
msgObj.write(msg_file);
System.out.println("EML file converted to MSG: " + msg_file);
}
catch (Exception e) {
e.printStackTrace();
}

错误原因

MAPIMessage(Apache POI HSMF库类)的设计目的是读取解析.msg格式文件,而非转换.eml到.msg。直接传入.eml路径时,它会尝试将.eml当作OLE2格式的.msg文件解析,自然触发"不是有效OLE2文档"的错误。

正确实现方案

通过JavaMail解析.eml提取邮件内容,再用Apache POI HSMF构建.msg文件,全程免费开源。

1. 依赖配置(Maven)

<dependencies>
    <!-- JavaMail 用于解析EML -->
    <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>jakarta.mail</artifactId>
        <version>2.0.1</version>
    </dependency>
    <!-- Apache POI HSMF 用于构建MSG -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-scratchpad</artifactId>
        <version>5.2.3</version>
    </dependency>
</dependencies>

2. 完整转换代码

import org.apache.poi.hsmf.MAPIMessage;
import org.apache.poi.hsmf.datatypes.AttachmentChunks;

import jakarta.mail.*;
import jakarta.mail.internet.MimeMessage;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class EmlToMsgConverter {

    public static void main(String[] args) {
        String emlFilePath = "C:\\temp\\_emai.eml";
        String msgFilePath = "C:\\temp\\msg_email.msg";

        try {
            // 解析EML文件
            MimeMessage mimeMessage = parseEml(emlFilePath);
            // 构建MSG对象并填充内容
            MAPIMessage msg = buildMsg(mimeMessage);
            // 写入MSG文件
            try (FileOutputStream fos = new FileOutputStream(msgFilePath)) {
                msg.write(fos);
                System.out.println("转换完成:" + msgFilePath);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static MimeMessage parseEml(String emlPath) throws Exception {
        Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);
        try (InputStream is = new FileInputStream(emlPath)) {
            return new MimeMessage(session, is);
        }
    }

    private static MAPIMessage buildMsg(MimeMessage mimeMsg) throws Exception {
        MAPIMessage msg = new MAPIMessage();

        // 填充基本属性
        msg.setSubject(mimeMsg.getSubject());
        msg.setSenderEmail(mimeMsg.getFrom()[0].toString());
        msg.setSentDate(mimeMsg.getSentDate());

        // 处理收件人
        Address[] toAddrs = mimeMsg.getRecipients(Message.RecipientType.TO);
        if (toAddrs != null) {
            List<String> toList = new ArrayList<>();
            for (Address addr : toAddrs) {
                toList.add(addr.toString());
            }
            msg.setDisplayTo(toList.toArray(new String[0]));
        }

        // 处理抄送(可选)
        Address[] ccAddrs = mimeMsg.getRecipients(Message.RecipientType.CC);
        if (ccAddrs != null) {
            List<String> ccList = new ArrayList<>();
            for (Address addr : ccAddrs) {
                ccList.add(addr.toString());
            }
            msg.setDisplayCC(ccList.toArray(new String[0]));
        }

        // 处理正文
        msg.setBodyText(getPlainContent(mimeMsg));
        // 若需保留HTML正文,可替换为msg.setBodyHtml(getHtmlContent(mimeMsg));

        // 处理附件
        if (mimeMsg.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) mimeMsg.getContent();
            for (int i = 0; i < multipart.getCount(); i++) {
                BodyPart part = multipart.getBodyPart(i);
                if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) {
                    try (InputStream is = part.getInputStream()) {
                        AttachmentChunks attachment = msg.createAttachment();
                        attachment.setFilename(part.getFileName());
                        attachment.setData(is.readAllBytes());
                    }
                }
            }
        }

        return msg;
    }

    private static String getPlainContent(MimeMessage msg) throws Exception {
        if (msg.isMimeType("text/plain")) {
            return msg.getContent().toString();
        } else if (msg.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) msg.getContent();
            for (int i = 0; i < multipart.getCount(); i++) {
                BodyPart part = multipart.getBodyPart(i);
                if (Part.INLINE.equalsIgnoreCase(part.getDisposition()) || part.getDisposition() == null) {
                    return getPlainContent((MimeMessage) part);
                }
            }
        }
        return "";
    }
}

3. 注意事项

  • 确保依赖版本兼容:Apache POI 5.x需搭配Jakarta Mail 2.x
  • 复杂邮件(如内嵌图片、多格式正文)需扩展解析逻辑,示例提供基础处理框架
  • 路径中的反斜杠需转义为\\,避免Java字符串解析错误

内容的提问来源于stack exchange,提问作者preet leelaramani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:34:58