Mpp 的導入導出
可以選用現成的 Mpxj 已有豐富的APi可用了,但是唯一不足的是MPXJ只能讀mpp文件,寫不支持但是支持寫mpx文件
只要不能寫mpp的原因在這里
Can I use MPXJ to write MPP files?
Not at present. Although it is technically feasible to generate an MPP file, the knowledge we have of the file structure is still relatively incomplete, despite the amount of data we are able to correctly extract. It is therefore likely to take a considerable amount of development effort to make this work, and it is conceivable that we will not be able to write the full set of attributes that MPXJ supports back into the MPP file - simply because we don't understand the format well enough. You are therefore probably better off using MSPDI which does support the full range of data items present in an MPP file.
ex:
File in = new File(m_basedir + "/sample.mpx");
ProjectFile mpx = new MPXReader().read(in);
out = File.createTempFile("junit", ".mpx");
MPXWriter writer = new MPXWriter();
writer.setUseLocaleDefaults(false);
writer.write(mpx, out);
實際上這里的ProjectFile 的成功讀取MPP文件接下來 通過它你就可以得心應手的獲取該Mpp文件的各種信息了
既然讀比較方便下面重點說說寫吧,畢竟這個才是大頭,好多人搞不定的地方。
基本上是一個思路 jni 處理,但是雖是用jni 也有不同的選擇的
1. 網上有人用 Jawin 的不可否認處理還算方便的 詳細請參考 這里不做過多說明;
2. 自己寫JNI封裝代碼 ,這個要求的功力恐怕也不小 (僅個人拙見);
3. 還有就是 用JACOB 調用ActiveXComponent 當然實際上還是JNI調用;
Jawin 僅支持32位的好像到2005年之后沒有什么改進的(是不是這個項目已經沒人維護了,還未可知),資料都比較老了,經再三斟酌我放棄了這個方案;而考慮到JNI的封裝的麻煩,而且需要的DLL庫的整理也比較繁瑣,就優先考慮用 ActiveXComponent處理。
既然可以寫mpx,那最直接的方案就是先用mpxj寫成mpx文件,剩下的考慮一件事就行了,就是把mpx轉換成mpp。
下面就是關於如何利用 jacob的 ActiveXComponent 和 mpxj 把mpx文件轉換成 mpp文件即可了
依賴 jacob-1.17 和 mpxj-4.4.0
1 /** 2 3 工具類 把mpx轉換成mpp ,這個依賴與系統已安裝了project 2003 4 5 **/ 6 7 8 9 public class Mpx2MppUtil { 10 11 12 13 private static ActiveXComponent activexComponent = null; 14 15 16 17 @SuppressWarnings({ "deprecation", "unused" }) 18 19 /** 20 21 * @param mpxFilePath mpx文件的文件路徑包括文件名和文件后綴 22 23 * 轉換執行成功,會在同文件夾下創建同文件名的mpp文件; 24 25 * 如:入參是 C:\project\test-kjdp.mpx 26 27 * 成功轉換后會在輸出 C:\project\test-kjdp.mpp 28 29 * 30 31 */ 32 33 public static boolean convertMpxToMpp(String mpxFilePath) { 34 35 int i = 0; 36 37 boolean retBooli = false; 38 39 if ((Mpx2MppUtil.isNullOrEmpty(mpxFilePath)) 40 41 || (mpxFilePath.length() < 5)) { 42 43 return retBooli; 44 45 } 46 47 int j = 0; 48 49 try { 50 51 int k = 0; 52 53 boolean retBoolk = false; 54 55 try { 56 57 ComThread.InitSTA(); 58 59 j = 1; 60 61 } catch (Error localError1) { 62 63 k = i; 64 65 retBoolk = retBooli; 66 67 try { 68 69 if (activexComponent != null) { 70 71 Dispatch.call(activexComponent, "Quit", 72 73 new Object[] { Integer.valueOf(0) }); 74 75 } 76 77 } catch (Exception localException5) { 78 79 80 81 } 82 83 try { 84 85 if (j != 0) { 86 87 ComThread.Release(); 88 89 } 90 91 } catch (Error localError4) { 92 93 } 94 95 return retBoolk; 96 97 } 98 99 activexComponent = new ActiveXComponent("MsProject.Application"); 100 101 try { 102 103 Variant localVariant = activexComponent.getProperty("Version"); 104 105 if (localVariant.toDouble() >= 12.0D) { 106 107 k = i; 108 109 try { 110 111 if (activexComponent != null) { 112 113 Dispatch.call(activexComponent, "Quit", 114 115 new Object[] { Integer.valueOf(0) }); 116 117 } 118 119 } catch (Exception localException6) { 120 121 } 122 123 try { 124 125 if (j != 0) { 126 127 ComThread.Release(); 128 129 } 130 131 } catch (Error localError5) { 132 133 } 134 135 return retBoolk; 136 137 // return k; 138 139 } 140 141 } catch (Exception localException1) { 142 143 LogFactory 144 145 .getLog(Mpx2MppUtil.class) 146 147 .warn("Please install the Microsoft Project 2003 on the server"); 148 149 } 150 151 activexComponent.setProperty("Visible", new Variant(false)); 152 153 activexComponent.setProperty("DisplayAlerts", new Variant(false)); 154 155 Dispatch.call(activexComponent, "FileOpen", 156 157 new Object[] { mpxFilePath }); 158 159 Dispatch.call( 160 161 activexComponent, 162 163 "FileSaveAs", 164 165 new Object[] { mpxFilePath.substring(0, 166 167 mpxFilePath.length() - 4) 168 169 + ".mpp" }); 170 171 i = 1; 172 173 retBooli = true; 174 175 } catch (Exception localError3) { 176 177 localError3.printStackTrace(); 178 179 } finally { 180 181 try { 182 183 if (activexComponent != null) 184 185 Dispatch.call(activexComponent, "Quit", 186 187 new Object[] { Integer.valueOf(0) }); 188 189 } catch (Exception localException7) { 190 191 } 192 193 try { 194 195 if (j != 0) 196 197 ComThread.Release(); 198 199 } catch (Error localError6) { 200 201 202 203 } 204 205 } 206 207 return retBooli; 208 209 } 210 211 212 213 public static boolean isNullOrEmpty(String myStr) { 214 215 return (myStr == null) || ("".equals(myStr.trim())); 216 217 } 218 219 220 221 } 222 223
1 /* 2 3 測試工具類的 先讀取一個mpp文件為ProjectFile 對象,在寫成 一個mpx文件 4 5 這后調用工具類 把mpx轉換成mpp ,這個依賴與系統已安裝了project 2003 6 7 */ 8 9 public class Mpx2MppUtilTest { 10 11 12 13 /** 14 15 * @param args 16 17 * @throws Exception 18 19 */ 20 21 public static void main(String[] args) throws Exception { 22 23 String projPath = "D:/works/dp_springworkspace20130220/mpx2mpp"; 24 25 String m_basedir = projPath + "/src/test/resources/test/mpp"; 26 27 File in = new File(m_basedir + "/test-kjdp.mpp"); 28 29 ProjectFile mpx = new MPPReader().read(in); 30 31 String pathname = projPath + "/src/test/resources/test/readmpp.mpx"; 32 33 File testmpx = new File(pathname); 34 35 MPXWriter mpxwriter = new MPXWriter(); 36 37 Locale locale = Locale.CHINESE; 38 39 mpxwriter.setLocale(locale ); 40 41 mpxwriter.write(mpx, testmpx); 42 43 boolean res = Mpx2MppUtil.convertMpxToMpp(pathname); 44 45 System.out.println(res); 46 47 } 48 49 50 51 } 52 53