mpp文件(軟件項(xiàng)目管理)

mpp文件是什么?

MPP是Microsoft Project項(xiàng)目管理軟件的文件擴(kuò)展名焦匈,此軟件旨在幫助個(gè)人跟蹤赘淮,組織或維護(hù)項(xiàng)目辕录。

在線打開mpp文件方式:https://projectviewercentral.com/freeviewer/

結(jié)構(gòu)

一個(gè)Project由Task,Resources梢卸,Calendar構(gòu)成走诞,Task與Calendar,Resources與Calendar都有關(guān)系蛤高。

MPXJ是一個(gè)開源的包蚣旱,網(wǎng)址:http://www.mpxj.org/howto-write-mpx.html
它的api文檔:http://www.mpxj.org/apidocs/index.html
它需要POI的支持。
它可以讀取MPP文件(不能寫MPP文件4鞫浮H獭!要經(jīng)過XML過渡恤批。异吻。。)
可以讀寫MPX文件开皿,MPX就是一個(gè)純文本文件涧黄,里面有TASK,Resource之類的信息赋荆,按一定格式書寫的笋妥。
Project 98及之前版本可以另存為MPX文件,從Project 2000開始就不支持另存為MPX格式了窄潭,
但是春宣,它們?nèi)匀豢梢宰x取MPX文件。

MPXJ的讀寫的類主要有這么幾個(gè):
讀:
net.sf.mpxj.mpp.MPPReader: reads Microsoft Project MPP files
net.sf.mpxj.mpx.MPXReader: reads Microsoft MPX files
net.sf.mpxj.mspdi.MSPDIReader: reads Microsoft MSPDI (XML) files
net.sf.mpxj.mpd.MPDIReader: reads Microsoft MPD files
net.sf.mpxj.planner.PlannerReader: reads Planner (XML) files
寫:
net.sf.mpxj.mpx.MPXWriter: writes Microsoft MPX files
net.sf.mpxj.mspdi.MSPDIWriter: writes Microsoft MSPDI (XML) files
net.sf.mpxj.planner.PlannerWriter: writes Planner (XML) files
所以嫉你,目前可以做的就是:
1.讀取MPP文件信息月帝,寫入DB之類的……
2.new 一個(gè)ProjectFile,寫入Task幽污,Resources嚷辅,Calendar之類的信息,
然后使用MPXWriter寫入MPX文件距误,然后用Project打開簸搞,好像會(huì)有個(gè)導(dǎo)入數(shù)據(jù)的對(duì)話框。

mpp效果圖

引入maven依賴

<dependency>
    <groupId>net.sf.mpxj</groupId>
    <artifactId>mpxj</artifactId>
    <version>8.0.8</version>
</dependency>

以xml格式寫出

核心方法


public String export(String projectId) {
        // 生成唯一標(biāo)識(shí)
        String uuid = UUID.randomUUID().toString();
        // 作者使用是linux系統(tǒng),這里方便演示直接路徑寫在方法里面准潭,作者建議寫在配置文件趁俊,方便維護(hù)
        String path = "/home/cqf/team/";

        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("project_id", projectId);
        // 獲取項(xiàng)目
        Project project = this.projectMapper.selectById(projectId);
        // 沒有找到該項(xiàng)目的信息
        if (ObjectUtils.isEmpty(project)) {
            return null;
        }
        // 導(dǎo)出文件名稱
        String fileName = path + uuid + project.getName() + ".xml";
         // 作者使用是linux系統(tǒng),這里方便演示直接路徑寫在方法里面刑然,作者建議寫在配置文件寺擂,方便維護(hù)
        File templatesFile = new File("/home/cqf/team/開辦新公司 - 導(dǎo)出模板.mpp");

        try {
            MPPReader mppRead = new MPPReader();
            ProjectFile file = mppRead.read(templatesFile);

            Task task = file.addTask();
            findChildrenTask(projectId, task, null, true);

            /*MPXWriter writer = new MPXWriter();
            // 設(shè)置簡體中文,防止亂碼
            writer.setLocale(Locale.CHINESE);
//        writer.setLocale(Locale.SIMPLIFIED_CHINESE);
            try {
                writer.write(file, fileName);
            } catch (IOException e) {
                e.printStackTrace();
            }*/

            //生成文件
            ProjectWriter writer = new MSPDIWriter();

            try {
                writer.write(file, fileName);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (MPXJException e) {
            e.printStackTrace();
        }

        // 返回文件名稱
        return fileName;
    }

遞歸查詢子任務(wù)


    /**
     * 查詢?nèi)蝿?wù)及子任務(wù)用于項(xiàng)目添加任務(wù)
     *
     * @param projectId
     * @param parentTask
     * @param parentId
     * @param firstFlag 是否是第一層
     */
    public void findChildrenTask(String projectId, Task parentTask, Integer parentId, boolean firstFlag) {
        List<MppTask> mppTasks;
        // 父id為空且為第一次則查詢,否則退出遞歸
        if (null == parentId && firstFlag) {
            // 獲取父級(jí)任務(wù)
            mppTasks = taskMapper.findParent(projectId);
        } else {
            // 當(dāng)父id為空時(shí),查詢?yōu)榭占唇Y(jié)束遞歸
            mppTasks = taskMapper.findByParentId(projectId, parentId);
        }

        for (int i = 0; i < mppTasks.size(); i++) {
            MppTask mppTask = mppTasks.get(i);

            // 獲取當(dāng)前任務(wù)的全部子任務(wù)
            List<MppTask> childrenTask = taskMapper.findByParentId(projectId, mppTask.taskId);
            Task task = parentTask.addTask();
            task.setName(mppTask.name);
            task.setStart(mppTask.startDate);
            task.setFinish(mppTask.endDate);
            task.setActualStart(mppTask.actualStart);
            task.setActualFinish(mppTask.actualFinish);
            task.setDuration(Duration.getInstance(5, TimeUnit.DAYS));
            task.setID(mppTask.taskId);

//                task.setOutlineLevel(parentTask.getOutlineLevel() + 1);
//                task.setUniqueID(parentTask.getUniqueID() + 1);
            if (childrenTask.size() > 0) {
                // 遞歸查詢子任務(wù)
                findChildrenTask(projectId, task, mppTask.taskId, false);
            } 
        }
    }

最后吐槽一下怔软,這玩意是真的惡心垦细,比opencv還惡心,案例太少了挡逼,不懂用它的api蝠检,它的api不僅全是英文,而且還沒有demo演示挚瘟,身為英語渣的我表示看不懂,關(guān)鍵是軟件項(xiàng)目管理的課沒有聽(因?yàn)橐咔橛绊懰撬螅系木W(wǎng)課)
果然乘盖,有些東西錯(cuò)過了,遲早要補(bǔ)回來憔涉。

參考地址
參考地址
參考地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末订框,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子兜叨,更是在濱河造成了極大的恐慌穿扳,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件国旷,死亡現(xiàn)場(chǎng)離奇詭異矛物,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)跪但,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門履羞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屡久,你說我怎么就攤上這事忆首。” “怎么了被环?”我有些...
    開封第一講書人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵糙及,是天一觀的道長。 經(jīng)常有香客問我筛欢,道長浸锨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任悴能,我火速辦了婚禮揣钦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘漠酿。我一直安慰自己冯凹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宇姚,像睡著了一般匈庭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上浑劳,一...
    開封第一講書人閱讀 52,785評(píng)論 1 314
  • 那天阱持,我揣著相機(jī)與錄音,去河邊找鬼魔熏。 笑死衷咽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蒜绽。 我是一名探鬼主播镶骗,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼躲雅!你這毒婦竟也來了鼎姊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤相赁,失蹤者是張志新(化名)和其女友劉穎相寇,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钮科,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡唤衫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跺嗽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片战授。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖桨嫁,靈堂內(nèi)的尸體忽然破棺而出植兰,到底是詐尸還是另有隱情,我是刑警寧澤璃吧,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布楣导,位于F島的核電站,受9級(jí)特大地震影響畜挨,放射性物質(zhì)發(fā)生泄漏筒繁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一巴元、第九天 我趴在偏房一處隱蔽的房頂上張望毡咏。 院中可真熱鬧,春花似錦逮刨、人聲如沸呕缭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽恢总。三九已至迎罗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間片仿,已是汗流浹背纹安。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留砂豌,地道東北人厢岂。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像阳距,于是被迫代替她去往敵國和親咪笑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361