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