
使用mpxj库在java中生成ms project兼容的xml文件时,无法直接控制ms project打开文件时的默认视图和列显示。本文将详细介绍一种有效的解决方案:通过创建和利用预设布局的ms project mpp模板文件,结合mpxj生成的数据,实现导入后自动显示“工作量”和“id”等指定列,从而优化用户体验。
理解MPXJ与MS Project视图的限制
MPXJ是一个强大的Java库,用于读写各种项目管理文件格式,包括Microsoft Project的MSPDI (Project Data Interchange) XML格式。然而,MSPDI XML文件主要关注项目数据的结构和内容(如任务、资源、工期、工作量等),而非其在Microsoft Project客户端中的视觉呈现或默认视图设置。这意味着,即使您在MPXJ中正确设置了任务的“工作量”和“ID”等数据,当MS Project打开由MPXJ生成的XML文件时,它通常会应用其默认视图,而不会自动显示这些特定的列,除非用户手动添加。
要实现打开文件时自动显示指定列,通常需要操作原生的.mpp文件格式,因为.mpp文件包含了项目数据以及所有视图、报表、宏等显示相关的配置。
核心解决方案:利用MS Project模板文件
鉴于MSPDI XML的限制,最实用且推荐的解决方案是结合MPXJ生成的数据与一个预先配置好的MS Project模板文件。这种方法允许您在MS Project中定义所需的显示布局,然后将MPXJ生成的数据导入到这个布局中。
1. 创建预设布局的MS Project模板文件
首先,您需要在Microsoft Project客户端中创建一个包含所需默认视图和列的模板文件。
- 打开Microsoft Project: 启动MS Project应用程序。
- 创建新项目: 选择“空白项目”创建一个新的空项目。
-
配置视图和列:
- 切换到您希望作为默认视图的视图(例如,“甘特图”视图)。
- 在表格区域,右键点击列标题,选择“插入列”。
- 添加您希望默认显示的列,例如“工作量 (Work)”和“ID”。
- 调整列的顺序、宽度以及其他任何视图设置,使其符合您的预期。
- 保存模板:: 将这个空白但已配置好视图的项目文件保存为.mpp格式。例如,您可以将其命名为 MyProjectTemplate.mpp。这个文件将作为您导入数据的基础。
2. 使用MPXJ生成项目数据(MSPDI XML)
接下来,您需要使用Java和MPXJ库来生成包含所有项目数据的MSPDI XML文件。确保在生成过程中,所有任务的“ID”和“工作量”等属性都已正确填充。
以下是一个简化的代码示例,展示了如何使用MPXJ设置任务的ID和工作量:
import net.sf.mpxj.Duration;
import net.sf.mpxj.ProjectFile;
import net.sf.mpxj.Task;
import net.sf.mpxj.TaskType;
import net.sf.mpxj.TimeUnit;
import net.sf.mpxj.mspdi.MSPDIWriter; // 用于生成XML文件
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Objects;
public class MpxjProjectGenerator {
public static void main(String[] args) {
ProjectFile project = new ProjectFile();
project.setName("Generated Project with Work and ID");
// 假设有一个Contract对象,这里简化为直接添加任务
Task contractElement = project.addTask();
contractElement.setName("Contract Phase");
contractElement.setStart(new Date()); // 设置开始日期
contractElement.setOutlineLevel(1);
contractElement.setID(1); // 设置ID
Task workpackage = contractElement.addTask();
workpackage.setName("Work Package A");
workpackage.setOutlineLevel(2);
workpackage.setID(2); // 设置ID
Task task = workpackage.addTask();
task.setName("Detailed Task 1");
task.setType(TaskType.FIXED_WORK);
task.setOutlineLevel(3);
task.setWork(Duration.getInstance(40, TimeUnit.HOURS)); // 设置工作量
task.setDuration(Duration.getInstance(5, TimeUnit.DAYS)); // 假设每天8小时工作
task.setRemainingWork(Duration.getInstance(40, TimeUnit.HOURS));
task.setID(3); // 设置ID
// 更多任务和资源分配...
// 示例中省略了资源分配部分,但原理类似,确保数据正确设置即可
try {
// 将项目保存为MSPDI XML文件
MSPDIWriter writer = new MSPDIWriter();
writer.write(project, new File("generated_project.xml"));
System.out.println("Project data saved to generated_project.xml");
} catch (IOException e) {
e.printStackTrace();
}
}
}在上述代码中,task.setWork() 方法用于设置任务的工作量,element.setID() 方法用于设置任务的ID。MPXJ会确保这些数据被正确地写入到MSPDI XML文件中。
3. 在MS Project中导入MSPDI并应用模板
这是关键的一步,它将MPXJ生成的数据与您预设的布局结合起来。
- 打开MS Project: 启动MS Project。
- 打开模板文件: 选择“文件” -> “打开”,然后浏览并打开您在第一步中创建的 MyProjectTemplate.mpp 文件。此时,您应该能看到模板中预设的视图和列(例如,“工作量”和“ID”列)。
- 导入MSPDI XML文件: 在已打开模板项目的情况下,再次选择“文件” -> “打开”。
- 选择XML文件: 浏览并选择您在第二步中由MPXJ生成的 generated_project.xml 文件。
-
选择导入选项: MS Project会弹出一个“导入向导”或“打开文件”对话框。在这里,您需要选择导入方式:
- “追加到现有项目” (Append the new project to the active project): 这是最常用的选项,它会将XML文件中的所有任务、资源等数据添加到当前打开的模板项目中。
- “更新现有项目” (Merge the new project into the active project): 如果XML文件中的任务与模板项目中的任务具有相同的ID,此选项可以用于更新现有任务数据。
- 选择目标项目: 确认目标是当前打开的 MyProjectTemplate.mpp 项目。
- 完成导入: 按照向导的指示完成导入过程。
导入完成后,MPXJ生成的项目数据将填充到 MyProjectTemplate.mpp 文件中,并且由于模板已经预设了视图,您将立即看到“工作量”和“ID”等列显示在默认视图中。
替代方案(非MPXJ直接控制)
虽然上述模板方法是使用MPXJ的最佳实践,但也有其他工具或方法可以考虑,尤其是在需要更直接的MPP文件生成和布局控制时:
- Aspose.Tasks: 这是一个商业库,它提供了更高级的功能,包括直接生成.mpp文件以及对项目布局、视图和报表进行更细粒度的控制。如果您对MPP文件有严格的布局要求,并且预算允许,Aspose.Tasks可能是一个选择。
- VBA脚本: 如果您的工作流涉及Excel数据源,并且您希望在Microsoft Project中直接自动化操作,可以考虑使用VBA(Visual Basic for Applications)。VBA可以直接在MS Project中编写脚本,从Excel读取数据,创建项目,并精确控制视图和列的显示。
注意事项与总结
- MPP与MSPDI的区别: 再次强调,.mpp文件是Microsoft Project的二进制原生格式,包含所有数据和显示配置;而MSPDI (.xml) 主要是数据交换格式,不包含完整的显示配置。
- 模板维护: 如果您的项目需要不同的默认视图,










