java 读取 解析微软Project .mpp 文件到甘特图

1.引入价包;

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.15</version>
        </dependency>
        <!-- 这一个是解析mpp文件的-->
        <dependency>
            <groupId>net.sf.mpxj</groupId>
            <artifactId>mpxj</artifactId>
            <version>5.6.4</version>
        </dependency>

        <dependency>
            <groupId>net.sf.jacob-project</groupId>
            <artifactId>jacob</artifactId>
            <version>1.14.3</version>
        </dependency>

2.解析Task :

package com.xyy.utils;

import java.io.Serializable;
import java.util.Date;

/**
 * Created by 14258 on 2017/3/24.
 */
public class SchProjectTask implements Serializable {
    private static final long serialVersionUID = -3323529750871923312L;
    /**
     * uuid
     */
    private String id;
    /**
     * 编号id
     */
    private String recordId;
    /**
     * 唯一id
     */
    private String uniqueId;
    /**
     * 父节点编号
     **/
    private String parentId;
    /**
     * 任务名称
     **/
    private String name;
    /**
     * 大纲水平
     */
    private Integer level;
    /**
     * 工期
     **/
    private Number duration;
    /**
     * 工期单位
     */
    private String durationTimeUnit;
    /**
     * 开始时间
     **/
    private Date startTime;
    /**
     * 结束时间
     **/
    private Date finishTime;
    /**
     * 完成百分比
     **/
    private Number percentageComplete;
    /**
     * 前置任务
     **/
    private String predecessors;
    /**
     * 所属项目文件id
     */
    private String ProId;

    //这里写set和get
    //这里写toStirng方法

}

3.要读取的文件的名字和作者,版本号

package com.xyy.utils;

import java.io.Serializable;

/**
 * Created by 14258 on 2017/3/24.
 */
public class SchProject implements Serializable {

    private static final long serialVersionUID = -3611636937880845938L;

    /**
     * uuid
     */
    private String id;
    /**
     * 文件名字
     */
    private String name;
    /**
     * 版本号 默认0
     */
    private Integer version;
    /**
     * 作者
     */
    private String author;

    //这里写set和get

    //这里写toStirng方法
}

4.使用自己写的工具类读取

package com.xyy.utils;


import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.xyy.TaskBean;
import net.sf.mpxj.*;
import net.sf.mpxj.mpp.MPPReader;
import net.sf.mpxj.mpx.MPXReader;
import net.sf.mpxj.mspdi.MSPDIReader;

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


  /**
  * @Author xuyangyang
  * @Describe  解析 project
  * @Date 2017/3/24
  * @Params  
  * @Return 
  */
public class MppUtil {

    /**
     * 顶级的父类Id
     **/
    private static final int TOP_PARENTID = 0;

    /**
     * 顶级的层次
     **/
    private static final int TOP_LEVEL = 1;

    /**
     * 导出生成mpp文件存放的路径
     **/
    private static final String FILE_PATH = "D:/tempFileSavePath.mpp";


    /**
     * 读取项目文件
     *
     * @param fileName 文件名 绝对路径
     * @return
     * @throws FileNotFoundException
     */
    private static ProjectFile readProject(String fileName)
            throws FileNotFoundException {
        InputStream is = new BufferedInputStream(new FileInputStream(fileName));
        is.mark(0);// 下面需要重复使用输入流,所以重新包装并设置重置标记

        ProjectFile mpx = null;
        try {
            mpx = new MPXReader().read(is);
        } catch (Exception ex) {
            try {
                is.reset();// 重置
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (mpx == null) {
            try {
                mpx = new MPPReader().read(is);
            } catch (Exception ex) {
                try {
                    is.reset();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        if (mpx == null) {
            try {
                mpx = new MSPDIReader().read(is);
            } catch (Exception ex) {
            }
        }
        return mpx;
    }


    /**
     * 项目文件--获取任务列表
     *
     * @throws FileNotFoundException
     * @Author xuyangyang
     * @Describe
     * @Date 2017/3/24
     * @Params fileName 读取.mpp文件路径
     * @Return
     */
    public static List<SchProjectTask> getTaskList(String fileName) throws FileNotFoundException {
        ProjectFile file = readProject(fileName);

//      SchProject schProject = new SchProject();
//      schProject.setName(file.getProjectHeader().getProjectTitle());
//      schProject.setAuthor(file.getProjectHeader().getAuthor());
//      schProject.setVersion(0);

        List<Task> tasks = file.getChildTasks();
        List<SchProjectTask> schProjectTaskList = new ArrayList<SchProjectTask>();
        if (!tasks.isEmpty()) {
            Task msTask = tasks.get(TOP_PARENTID);
            schProjectTaskList = listHierarchy(msTask, TOP_PARENTID);
        }
        return schProjectTaskList;
    }

    /**
     * 获取任务的子任务
     *
     * @param parentId 父任务Id
     * @Author xuyangyang
     * @Describe
     * @Date 2017/3/24
     * @Params task 任务
     * @Return
     */

    private static List<SchProjectTask> listHierarchy(Task msTask, int parentId) {
        List<Task> childTasks = msTask.getChildTasks();
        List<SchProjectTask> schProjectTaskList = new ArrayList<SchProjectTask>();
        SchProjectTask schProjectTask = null;
        if (!childTasks.isEmpty()) {
            for (Task task : childTasks) {
                schProjectTaskList.add(getTaskBean(schProjectTask, task, parentId));
                schProjectTaskList.addAll(listHierarchy(task, task.getID()));
            }
        }
        return schProjectTaskList;
    }


    /**
     * 获取任务的具体字段
     *
     * @Author xuyangyang
     * @Describe
     * @Date 2017/3/24
     * @Params schProjectTask 任务Bean
     * @Params task 任务
     * @Params parentId 父类Id
     * @Return schProjectTask bean;
     */
    private static SchProjectTask getTaskBean(SchProjectTask schProjectTask, Task task, Integer parentId) {

        schProjectTask = new SchProjectTask();
        schProjectTask.setRecordId(task.getID().toString());
        schProjectTask.setUniqueId(task.getUniqueID().toString());
        schProjectTask.setParentId(parentId.toString());
        schProjectTask.setName(task.getName());
        schProjectTask.setDuration(task.getDuration().getDuration());
        schProjectTask.setDurationTimeUnit(task.getDuration().getUnits().getName());
        schProjectTask.setStartTime(task.getStart());
        schProjectTask.setFinishTime(task.getFinish());
        schProjectTask.setPercentageComplete(task.getPercentageComplete());
        schProjectTask.setLevel(task.getOutlineLevel());
//      schProjectTask.setPredecessors();
//      schProjectTask.setProId();

        List<String> preLists = new ArrayList<String>();

        List<Relation> predecessors = task.getPredecessors();
        if (predecessors != null && predecessors.isEmpty() == false) {
            for (Relation relation : predecessors) {
                Task tragetTask = relation.getTargetTask();
                Integer targetTaskRecordId = tragetTask.getID();
                Integer targetTaskUniqueId = tragetTask.getUniqueID();
                String m_type = relation.getType().toString();//SS///FS
                String m_lag = relation.getLag().toString();//10.0d//0.0d//-35.0d

//              if (m_type.equals("FS")){m_type = "";}
//              if (m_lag.equals("0.0d")){m_lag="";}else if(m_lag.equals("")){
//                }else if (!m_lag.startsWith("-") && !m_lag.equals("0.0d")){m_lag="+"+m_lag;
//              }
//              String s = " 工作日";
//              String predecessor;
//              if (m_type.equals("") || m_lag.equals("")){predecessor = targetRaskId.toString();
//              } else {predecessor = targetRaskId+m_type+m_lag+s;
//              }

                String predecessor = targetTaskRecordId + ":"+targetTaskUniqueId+":"+ m_type + ":" + m_lag;
                preLists.add(predecessor);}
        }
        schProjectTask.setPredecessors(listToString(preLists));
        return schProjectTask;
    }

    /**
     * List 转为 String
     * @Author xuyangyang
     * @Describe
     * @Date 2017/3/24
     * @Params List 对象集合
     * @Return String
     */
    public static String listToString(List list) {
        StringBuilder sb = new StringBuilder();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                if (i < list.size() - 1) {
                    sb.append(list.get(i) + ",");
                } else {
                    sb.append(list.get(i));
                }
            }
        }
        return sb.toString();
    }




/**
 * 创建mpp文件
 *
 * @param taskBeanList 任务列表
 * @throws Exception
 */

    public static void createMppFile(List<TaskBean> taskBeanList) throws Exception {
        File file = new File(FILE_PATH);
        if (file.exists()) {
            file.delete();
        }
        if (taskBeanList != null && taskBeanList.size() > 0) {
            ActiveXComponent app = null;
            try {
                app = new ActiveXComponent("MSProject.Application");
                app.setProperty("Visible", new Variant(false));
                Dispatch projects = app.getProperty("Projects").toDispatch();
                Dispatch project = Dispatch.call(projects, "Add").toDispatch();//添加一个项目
                Dispatch tasks = Dispatch.get(project, "Tasks").toDispatch();//生成一个task集合
                //生成Task
                TaskBean topTaskBean = getTopTaskBean(taskBeanList);
                createTreeTable(tasks, topTaskBean, TOP_LEVEL, taskBeanList);
                //另存为
                Dispatch.invoke(project, "SaveAs", Dispatch.Method, new Object[]{FILE_PATH, new Variant(0)}, new int[1]);
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("aaaaaaaaaa");
            } finally {
                if (app != null)
                    app.invoke("Quit", new Variant[]{});
            }
        }
    }

    /**
     * 创建树形结构
     *
     * @param tasks        任务集合
     * @param taskBean     任务Bean
     * @param level        层次
     * @param taskBeanList 任务列表
     */
    private static void createTreeTable(Dispatch tasks, TaskBean taskBean, int level, List<TaskBean> taskBeanList) {
        Dispatch task = Dispatch.call(tasks, "Add").toDispatch();
        setTaskValue(task, taskBean, level);
        List<TaskBean> sonTaskBeanList = getSonTaskBean(taskBeanList, taskBean);
        if (!sonTaskBeanList.isEmpty()) {
            for (TaskBean sonTaskBean : sonTaskBeanList) {
                createTreeTable(tasks, sonTaskBean, level + 1, taskBeanList);
            }
        }
    }

    /**
     * 获取所有的子任务
     *
     * @param taskBeanList   任务列表
     * @param parentTaskBean 父级任务Bean
     * @return
     */
    private static List<TaskBean> getSonTaskBean(List<TaskBean> taskBeanList, TaskBean parentTaskBean) {
        List<TaskBean> sonTaskBeanList = new ArrayList<TaskBean>();
        for (TaskBean taskBean : taskBeanList) {
            if (taskBean.getParentId() == parentTaskBean.getId()) {
                sonTaskBeanList.add(taskBean);
            }
        }
        return sonTaskBeanList;
    }

    /**
     * 获取顶级任务
     *
     * @param taskBeanList 任务列表
     * @return
     */
    private static TaskBean getTopTaskBean(List<TaskBean> taskBeanList) {
        for (TaskBean taskBean : taskBeanList) {
            if (taskBean.getParentId() == TOP_PARENTID)
                return taskBean;
        }
        return null;
    }

    /**
     * 给任务设置属性
     *
     * @param task     任务指针
     * @param taskBean 任务Bean
     * @param level    层次
     */
    private static void setTaskValue(Dispatch task, TaskBean taskBean, int level) {
        Dispatch.put(task, "Name", taskBean.getName());
//      Dispatch.put(task, "Duration",Duration.getInstance(5, TimeUnit.DAYS));
        Dispatch.put(task, "Start", taskBean.getStartTime());
        Dispatch.put(task, "Finish", taskBean.getFinishTime());
//      Dispatch.put(task, "Duration",taskBean.getDuration());
//      Dispatch.put(task, "PercentageComplete",NumberUtility.getDouble(taskBean.getPercentageComplete()));
        Dispatch.put(task, "OutlineLevel", level);
        Dispatch.put(task, "ResourceNames", taskBean.getResource());
    }

    /**
     * 获取任务中的资源
     *
     * @param task 任务
     * @return
     */
    private static String listTaskRes(Task task) {
        StringBuffer buf = new StringBuffer();
        List<ResourceAssignment> assignments = task.getResourceAssignments();//获取任务资源列表
        if (assignments != null && !assignments.isEmpty()) {
            ResourceAssignment assignment = (ResourceAssignment) assignments.get(0);//只获取第一个资源
            Resource resource = assignment.getResource();
            if (resource != null)
                buf.append(resource.getName());
        }
        return buf.toString();
    }

    public static void main(String[] args) throws Exception {
//        Project project=MppUtil.getTaskList("D:/环境科学楼含机电.mpp");
//        List<TaskBean>taskBeanList=project.getTaskBeanList();
//        System.out.println(taskBeanList.size());
//        for(TaskBean task:taskBeanList){
//        System.out.println(task);
//        }
//        createMppFile(taskBeanList);


        List<SchProjectTask> taskBeanList = MppUtil.getTaskList("D:/环境科学楼含机电.mpp");
        System.out.println(taskBeanList.size());
        for (SchProjectTask task : taskBeanList) {
            System.out.println(task);
        }
        //  createMppFile(taskBeanList);
    }
}

5.测试的文件:链接:http://pan.baidu.com/s/1o8sIN1K 密码:wefr

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
Microsoft Project 是一款常用的项目管理软件,它使用的文件格式为 .mpp。如果需要解析 .mpp 文件,可以使用 Microsoft Project 软件自带的 API,也可以使用第三方库或者工具实现。 Microsoft Project 提供了 VBA 编程接口,可以通过编写 VBA 宏实现对 .mpp 文件解析。具体步骤如下: 1. 打开 Microsoft Project 软件,按下 Alt + F11 打开 VBA 编辑器。 2. 在 VBA 编辑器中,插入一个新的模块。 3. 在模块中编写 VBA 代码,使用 Project 对象和 Task 对象来访问 .mpp 文件中的数据。例如,以下代码可以输出 .mpp 文件中所有任务的名称: ``` Sub ParseMppFile() Dim proj As Project Set proj = Application.ActiveProject Dim task As Task For Each task In proj.Tasks Debug.Print task.Name Next task End Sub ``` 此外,还可以使用第三方库或者工具实现 .mpp 文件解析。例如,有一些 Python 库可以读取和操作 .mpp 文件,如 pympp 和 pywin32。使用这些库,可以在 Python 环境中编写代码来读取 .mpp 文件中的数据。例如,以下 Python 代码可以读取 .mpp 文件中所有任务的名称: ``` import win32com.client app = win32com.client.Dispatch("MSProject.Application") app.Visible = True proj = app.FileOpenEx("path/to/mpp/file.mpp") for task in proj.Tasks: print(task.Name) proj.Close() app.Quit() ``` 需要注意的是,使用第三方库或者工具解析 .mpp 文件可能会受到 Microsoft Project 版本和 .mpp 文件格式的限制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值