Java利用mpxj解析mpp格式文件

转载请注明来源:http://blog.csdn.net/loongshawn/article/details/51038051

1、mpp文件介绍

MPP是Microsoft Project项目管理软件的文件扩展名,此软件旨在帮助个人跟踪,组织或维护项目。

2、mpp显示效果

这里写图片描述

可以通过在线的mpp阅读工具打开的,该工具免费,但限制了上传文件大小不超过2M。
https://www.projectplan365.com/projectviewernow/tViews.aspx#

3、mpp结构说明

通过上图可以看出,文件主体内容就是一条一条的记录,记录内容包括:任务ID、任务名、Duration、Start日期、Finish日期、Predecessors业务流、自定义字段。

接下来,我们先来了解下mpp文档的解析工具类,目前主要是通过MPXJ工具类来解析该文件。

MPXJ官方网站:http://mpxj.sourceforge.net

MPXJ官方API说明文档:http://mpxj.sourceforge.net/apidocs/index.html

Package net.sf.mpxj.mpp
上面这个包是处理MPP文件解析的主要集合,通过net.sf.mpxj.mpp.MPPReader类来构建读文件管道。

每条具体的任务都需要通过这个类net.sf.mpxj.Task来解析。

// 普通任务ID
Integer task_id =task.getID();
// 独立任务ID
Integer task_unique_id =task.getUniqueID();
// 大纲ID
Integer task_outline_level =task.getOutlineLevel();
// 任务周期
double task_duration =task.getDuration().getDuration();
// 任务名
String task_name = task.getName();
// 任务开始日期
Date task_start_date = task.getStart();
// 任务结束日期
Date task_finish_date = task.getFinish();
// 任务流
List<Relation> task_predecessors = task.getPredecessors();         

4、mpp解析代码

解析线上mpp文件,同时获取TaskInfo

// NO.1 解析mpp文件,同时获取TaskInfo
    public static List<TaskInfo> readInputStream(InputStream in,String fileName){

        List<TaskInfo> taskList = new ArrayList<TaskInfo>();
        InputStream ins = in;

        try{            
            MPPReader mppRead = new MPPReader();
            ProjectFile pf = mppRead.read(in);
            logger.info("MPXJUtils.method [readInputStream]: fileName-" + fileName);

            List<Task> tasks = pf.getAllTasks();
            logger.info("MPXJUtils.method [readInputStream]: taskSize-" + tasks.size());

            for (int i = 0; i < tasks.size(); i++) {
                Task task = tasks.get(i);

                Integer task_id = task.getID();
                Integer task_unique_id = task.getUniqueID();
                Integer task_outline_level = task.getOutlineLevel();
                double task_duration = task.getDuration().getDuration();
                String task_name = task.getName();
                Date task_start_date = task.getStart();
                Date task_finish_date = task.getFinish();
                List<Relation> task_predecessors = task.getPredecessors();                              
                logger.info("MPXJUtils.method [readInputStream] taskInfo:" + task_id + "|" + task_unique_id + "|" + task_outline_level + "|" + task_duration + "|" + task_start_date + "|" + task_finish_date + "|" + task_predecessors);

                // 封装TaskInfo
                java.sql.Date sqlStartDate = Str2Date.getUKDate(task_start_date.toString());                // StartDate转换
                java.sql.Date sqlFinishDate = Str2Date.getUKDate(task_finish_date.toString());              // FinishDate转换
                StringBuffer sb = new StringBuffer();
                if(task_predecessors != null){
                    if(task_predecessors.size() > 0){
                        for(Relation relation : task_predecessors){
                            Integer targetTaskId = relation.getTargetTask().getID();
                            if(sb.length() == 0){
                                sb.append(targetTaskId);
                            }else{
                                sb.append(","+targetTaskId);
                            }
                        }
                    }
                }
                String task_predecessors_str = sb.toString();                                               // 任务流文本

                TaskInfo taskInfo = new TaskInfo();
                taskInfo.setTask_id(task_id);
                taskInfo.setTask_unique_id(task_unique_id);
                taskInfo.setTask_outline_level(task_outline_level);
                taskInfo.setTask_name(task_name);
                taskInfo.setTask_duration(task_duration);
                taskInfo.setTask_start_date(sqlStartDate);
                taskInfo.setTask_finish_date(sqlFinishDate);
                taskInfo.setTask_predecessors(task_predecessors_str);

                taskList.add(taskInfo);             
            }               
        }catch (MPXJException e) {
            logger.info("MPXJUtils.method [readInputStream]: MPXJException-" + e);
            return null;  
        } catch (Exception e) { 
            logger.info("MPXJUtils.method [readInputStream]: MPXJException-" + e);
            return null;  
        } finally {         
            try {
                ins.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                logger.info("MPXJUtils.method [readInputStream]: IOException-" + e);
                return null;  
            }
        }
        return taskList;
    }

封装过的TaskInfo

public class TaskInfo {

    private int project_id;                         // 所属项目ID
    private int task_id;                            // 任务ID
    private int task_unique_id;                     // 任务唯一ID
    private int parent_id;                          // 父任务ID
    private int task_outline_level;                 // 任务级别
    private String task_name;                       // 任务名称
    private double task_duration;                   // 任务工期
    private java.sql.Date task_start_date;          // 任务开始时间
    private java.sql.Date task_finish_date;         // 任务结束时间
    private String task_predecessors;               // 任务流
    private String task_operator;                   // 负责人

    public int getProject_id() {
        return project_id;
    }
    public void setProject_id(int project_id) {
        this.project_id = project_id;
    }
    public int getTask_id() {
        return task_id;
    }
    public void setTask_id(int task_id) {
        this.task_id = task_id;
    }
    public int getTask_unique_id() {
        return task_unique_id;
    }
    public void setTask_unique_id(int task_unique_id) {
        this.task_unique_id = task_unique_id;
    }
    public int getParent_id() {
        return parent_id;
    }
    public void setParent_id(int parent_id) {
        this.parent_id = parent_id;
    }
    public int getTask_outline_level() {
        return task_outline_level;
    }
    public void setTask_outline_level(int task_outline_level) {
        this.task_outline_level = task_outline_level;
    }
    public double getTask_duration() {
        return task_duration;
    }
    public void setTask_duration(double task_duration) {
        this.task_duration = task_duration;
    }
    public Date getTask_start_date() {
        return task_start_date;
    }
    public void setTask_start_date(Date task_start_date) {
        this.task_start_date = task_start_date;
    }
    public Date getTask_finish_date() {
        return task_finish_date;
    }
    public void setTask_finish_date(Date task_finish_date) {
        this.task_finish_date = task_finish_date;
    }
    public String getTask_predecessors() {
        return task_predecessors;
    }
    public void setTask_predecessors(String task_predecessors) {
        this.task_predecessors = task_predecessors;
    }
    public String getTask_operator() {
        return task_operator;
    }
    public void setTask_operator(String task_operator) {
        this.task_operator = task_operator;
    }
    public String getTask_name() {
        return task_name;
    }
    public void setTask_name(String task_name) {
        this.task_name = task_name;
    }
}

解析本地mpp文件方法,供测试使用

public static List<TaskInfo> readFile(){

        List<TaskInfo> taskList = new ArrayList<TaskInfo>();
        try{    
            File file = new File("/Users/ffff/Downloads/计划(含月度版)V0.10-20160222.mpp");
            MPPReader mppRead = new MPPReader();
            ProjectFile pf = mppRead.read(file);
            logger.info("MPXJUtils.method [readFile]: fileName-" + file.getName());

            List<Task> tasks = pf.getAllTasks();
            logger.info("MPXJUtils.method [readFile]: taskSize-" + tasks.size());

            for (int i = 0; i < tasks.size(); i++) {
                Task task = tasks.get(i);

                Integer task_id = task.getID();
                Integer task_unique_id = task.getUniqueID();
                Integer task_outline_level = task.getOutlineLevel();
                double task_duration = task.getDuration().getDuration();
                Date task_start_date = task.getStart();
                Date task_finish_date = task.getFinish();
                List<Relation> task_predecessors = task.getPredecessors();                              
                logger.info("MPXJUtils.method [readFile] taskInfo:" + task_id + "|" + task_unique_id + "|" + task_outline_level + "|" + task_duration + "|" + task_start_date + "|" + task_finish_date + "|" + task_predecessors);

                // 封装TaskInfo
                java.sql.Date sqlStartDate = Str2Date.getUKDate(task_start_date.toString());            // StartDate转换
                java.sql.Date sqlFinishDate = Str2Date.getUKDate(task_finish_date.toString());          // FinishDate转换
                StringBuffer sb = new StringBuffer();
                if(task_predecessors != null){
                    if(task_predecessors.size() > 0){
                        for(Relation relation : task_predecessors){
                            Integer targetTaskId = relation.getTargetTask().getID();
                            if(sb.length() == 0){
                                sb.append(targetTaskId);
                            }else{
                                sb.append(","+targetTaskId);
                            }
                        }
                    }
                }
                String task_predecessors_str = sb.toString();                                           // 任务流文本

                TaskInfo taskInfo = new TaskInfo();
                taskInfo.setTask_id(task_id);
                taskInfo.setTask_unique_id(task_unique_id);
                taskInfo.setTask_outline_level(task_outline_level);
                taskInfo.setTask_duration(task_duration);
                taskInfo.setTask_start_date(sqlStartDate);
                taskInfo.setTask_finish_date(sqlFinishDate);
                taskInfo.setTask_predecessors(task_predecessors_str);

                taskList.add(taskInfo);             
            }               
        }catch (MPXJException e) {
            logger.info("MPXJUtils.method [readFile]: MPXJException-" + e);
            return null;  
        } catch (Exception e) { 
            logger.info("MPXJUtils.method [readFile]: MPXJException-" + e);
            return null;  
        }       
        return taskList;
    }

本地测试,输出mpp文件结果:
这里写图片描述

获取子任务间的所属父子关系

// NO.2 获取TaskInfo之间的父子关联关系
    public static List<TaskInfo> refreshTaskInfo(List<TaskInfo> taskList){

        List<Map<String,Integer>> tempTaskOutLine = new ArrayList<Map<String,Integer>>();
        for(TaskInfo taskInfo : taskList){

            int taskId = taskInfo.getTask_id();
            int taskOutLineLevel = taskInfo.getTask_outline_level();            
            int listSize = tempTaskOutLine.size();
            logger.info("MPXJUtils.method [refreshTaskInfo1]: taskId-" + taskId + ",taskOutLineLevel-" + taskOutLineLevel + ",listSize-" + listSize);

            // 初始化taskOutLineLevel
            if(listSize > 2){               
                if(taskOutLineLevel == 1){                  
                    for(int i=listSize;i>2;i--){
                        tempTaskOutLine.remove(i-1);
                    }
                    listSize = 2;   
                    logger.info("MPXJUtils.method [refreshTaskInfo2]: taskId-" + taskId + ",taskOutLineLevel-" + taskOutLineLevel + ",listSize-" + listSize);
                }               
            }


            Map<String,Integer> map = new HashMap<String,Integer>();
            map.put("taskId", taskId);
            map.put("taskOutLineLevel", taskOutLineLevel);

            if(listSize == 0){

                if(taskOutLineLevel == 0){
                    tempTaskOutLine.add(map);
                }else{
                    return null;
                }

            }else{

                Map<String,Integer> lastMap = tempTaskOutLine.get(listSize-1);
                int lastTaskId = lastMap.get("taskId");
                int lastTaskOutLineLevel = lastMap.get("taskOutLineLevel");

                if(taskOutLineLevel > lastTaskOutLineLevel){

                    tempTaskOutLine.add(map);
                    taskInfo.setParent_id(lastTaskId);
                }else if(taskOutLineLevel == lastTaskOutLineLevel){ 

                    tempTaskOutLine.set(taskOutLineLevel, map);

                    Map<String,Integer> lastMap1 = tempTaskOutLine.get(taskOutLineLevel-1);
                    int lastTaskId1 = lastMap1.get("taskId");
                    taskInfo.setParent_id(lastTaskId1);
                }else if(taskOutLineLevel < lastTaskOutLineLevel){                  

                    tempTaskOutLine.set(taskOutLineLevel, map);

                    Map<String,Integer> lastMap2 = tempTaskOutLine.get(taskOutLineLevel-1);
                    int lastTaskId2 = lastMap2.get("taskId");
                    taskInfo.setParent_id(lastTaskId2);
                }
            }                       
        }

        return taskList;
    }   

5、数据存储

将解析的结果,经过子任务排序,即获取每条子任务的父任务,大家可以理解为书本目录的大纲。
这里写图片描述

下面看看数据存储到数据库后的效果:
这里写图片描述

转载于:https://my.oschina.net/abcijkxyz/blog/724866

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值