msg形式のメールファイルをemlファイルに変換する

 数年前にjavamailで作ったメールを受信した後の業務を自動化するツールを、今でもいろいろ機能追加をしているのですが、機能を追加・変更する時に、利用者から対象のメールをemlで提供してもらってテストしています。
 でも、outlookユーザーはmsgでしか提供出来ませんというので、emlへ変換したいのですが、ネットに転がってるツールを使ってもイマイチ変換できません。。
 なら作ろうと調べた所、javaならjotlmsgというのがあったのですが、日本語が文字化けします。
 結局、apache poiでoutlookのmsgを扱えるようなので、msgファイルを読み込んでemlファイルへ出力するという形にしました。

 実行時の引数を、msgファイルを入れたパス、emlファイルを吐き出すパスで指定します。

 何件かのmsgファイルを試した所、htmlで取れるケースが無かった。。メソッド的にはあるはずなのに。。
 その為、完全にemlファイルで再現出来るというレベルにはなりませんでしたが、本文テキストと添付ファイルはemlファイルに出力できているので、まあここまででよいかと。

package jp.esoro.mail.main;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hsmf.MAPIMessage;
import org.apache.poi.hsmf.datatypes.AttachmentChunks;
import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;

public class MsgtoEml {
	public static void main(String[] args)  {
		String msgdir = null;
		String emldir = null;
		for(String arg : args){å
			if(msgdir == null){
				msgdir = arg;
			}
			else{
				emldir = arg;
			}
		}
		if(msgdir == null || emldir == null){
			System.out.println("first arg is msg-file path. second arg is export-eml path");
			System.exit(100);
		}
    	File dir = new File(msgdir);
    	File[] files = dir.listFiles();  
    	
        Properties prop = new Properties();
	    Session session = Session.getDefaultInstance(prop, null);
	    
		for(File file: files){
			if( file.isDirectory() ) {
				continue;
			}
			if(StringUtils.endsWithIgnoreCase(file.getName(),"msg")){
				try {
					FileOutputStream fos = new FileOutputStream(emldir + "/" + StringUtils.replaceIgnoreCase(file.getName(), "msg", "eml"));
					
					MAPIMessage  msg = new MAPIMessage(file);
					MimeMessage eml = new MimeMessage(session);
					String headerValue = "";
					String headerKey = "";
					for(String head: msg.getHeaders()){
						if(head.startsWith(" ")){
							headerValue = headerValue + System.lineSeparator() +head;
						}
						else{
							if(headerKey.length() > 0){
								eml.setHeader(headerKey, headerValue);
							}
							String[] h = head.split(":");
							if(h.length > 1){
								headerKey = head.split(":")[0];
								headerValue = head.split(":")[1];
							}
						}
					}
					eml.setSubject(msg.getSubject(), "UTF-8");
					if(msg.getAttachmentFiles() != null){
						MimeBodyPart mbody = new MimeBodyPart();
						try {
							mbody.setContent(msg.getHtmlBody(),"text/html; charset=UTF-8");
						} catch (ChunkNotFoundException e) {
							mbody.setContent(msg.getTextBody(),"text/plain; charset=UTF-8");
						}
						Multipart mp = new MimeMultipart();
						mp.addBodyPart(mbody);
						for (AttachmentChunks chunks : msg.getAttachmentFiles()){
							MimeBodyPart mbAttachment = new MimeBodyPart();
							mbAttachment.setContent(chunks.getAttachData().getValue(), "application/octet-stream");
							mbAttachment.setFileName(chunks.getAttachFileName().getValue());
							mp.addBodyPart(mbAttachment);
						}
						eml.setContent(mp);
					}
					else{
						try {
						eml.setContent(msg.getHtmlBody(),"text/html; charset=UTF-8");
						} catch (ChunkNotFoundException e) {
							eml.setContent(msg.getTextBody(),"text/plain; charset=UTF-8");
						}
					}
					eml.setSentDate(msg.getMessageDate().getTime());
					eml.writeTo(fos);
					msg.close();
					fos.close();
					System.out.println("["+file.getName() + "] msg exchanged to eml");
					
				} catch (IOException | MessagingException | ChunkNotFoundException e) {
					System.out.println("[" +file.getName() + "] msg export to eml is fail ");
					e.printStackTrace();
				}
			}
		}
	}
}
カテゴリー: Java