java解析mpp文件(包含层级关系)

article/2025/11/8 23:49:57

导入数据
我用的是递归循环的,不限制有多少子级关系都可以拿到

首先引入解析mpp所需依赖

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

解析所用实体类,每个字段都有对应意思

public class ArrowDiagramImport extends Model<ArrowDiagramImport> {@TableId(value = "ID")private String id;/*** 序号*/@TableField(value = "SERIAL_NUMBER",exist = true  )private String serialNumber;/*** 节点名称*/@TableField(value = "TASK_NAME",exist = true  )private String taskName;/*** 前置节点ID*/@TableField(value = "PARENT_ID",exist = true  )private String parentId;/*** 工期*/@TableField(value = "DURATION",exist = true  )private Double duration;/*** 计划开始时间*/@TableField(value = "PLAN_START_DATE",exist = true  )@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd")private Date planStartDate;/*** 计划结束时间*/@TableField(value = "PLAN_END_DATE",exist = true  )@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd")private Date planEndDate;/*** 层级*/@TableField(value = "plan_level",exist = true  )private String planLevel;/*** 是否拆分 0是 1否(代表该条数据是不是父节点)*/@TableField(value = "is_not_split",exist = true  )private String isNotSplit;/*** 拆分后子任务的父节点序号*/@TableField(value = "split_parent_id",exist = true  )private String splitParentId;}

核心代码

    public void mppFileAnalysis(MultipartFile multipartFile) {try {//读取文件的组件MPPReader mppReader = new MPPReader();//注意,如果在这一步出现了读取异常,肯定是版本不兼容,换个版本试试ProjectFile pf = mppReader.read(multipartFile.getInputStream());//从文件中获取的任务对象List<Task> tasks = pf.getChildTasks();//解析后数据存入对象List<ArrowDiagramImport> importList = new ArrayList<>();//递归解析方法childrenTask(tasks.get(0).getChildTasks(), new ArrowDiagramImport(), importList);for (ArrowDiagramImport diagramImport : importList) {System.out.println(diagramImport.getTaskName());}} catch (Exception e) {e.printStackTrace();}}

递归方法

taskList 循环解析对象,rtSingleArrowDiagramImport 代表当前循环的数据是它的子级,importList 循环解析后数据存入的集合

    //taskList 循环解析对象,rtSingleArrowDiagramImport   代表当前循环的数据是它的子级,importList   循环解析后数据存入的集合public void childrenTask(List<Task> taskList, ArrowDiagramImport rtSingleArrowDiagramImport, List<ArrowDiagramImport> importList) {//设置层级,如果等于空,则代表是第一层级,不为空则在父级节点的层级基础上+1int levelNum;if (StringUtils.isEmpty(rtSingleArrowDiagramImport.getPlanLevel())) {levelNum = 1;} else {levelNum = Integer.parseInt(rtSingleArrowDiagramImport.getPlanLevel()) + 1;}//循环所有节点for (Task task : taskList) {ArrowDiagramImport diagramImport = new ArrowDiagramImport();diagramImport.setId(StringUtils.getUUID());diagramImport.setSerialNumber(task.getID().toString());diagramImport.setSplitParentId(rtSingleArrowDiagramImport.getSerialNumber());//将上一级目录的Id赋值给下一级的ParentIddiagramImport.setPlanLevel(String.valueOf(levelNum));//层级diagramImport.setTaskName(task.getName());//这个是获取文件中的“任务名称”列的数据diagramImport.setDuration(task.getDuration().getDuration());//获取的是文件中的“工期”diagramImport.setPlanStartDate(task.getStart());//获取文件中的 “开始时间”diagramImport.setPlanEndDate(task.getFinish());//获取文件中的 “完成时间”diagramImport.setParentId(getParentIds(task));if (task.getChildTasks().size() > 0) {diagramImport.setIsNotSplit(DelFlagType.Normal.getType());childrenTask(task.getChildTasks(), diagramImport, importList);//继续进行递归,当前保存的只是父任务的信息} else {diagramImport.setIsNotSplit(DelFlagType.Delete.getType());}importList.add(diagramImport);}}

该方法是为了获取前置节点的关系,包含特殊前置关系

 public String getParentIds(Task task) {String parentId = "";if (task.getPredecessors().size() > 0) {for (Relation relation : task.getPredecessors()) {//前置节点IDString id = relation.getTargetTask().getID().toString();//关联前置节点的关系 FS/FF/SS/SFString type = relation.getType().toString();//与前置节点关系的天数Integer duration = (int) relation.getLag().getDuration();//如果类型=FS,并且天数为0,则代表没有特殊关系if (type.equals(DiagramPlanType.FS.getCode()) && duration == 0.0) {parentId += id + ",";} else {String durationStr = "";if (duration > 0.0) {durationStr = "+" + duration + "工日";} else if (duration < 0.0) {durationStr = duration.toString() + "工日";}parentId += id + type + durationStr + ",";}}parentId = parentId.substring(0, parentId.length() - 1);}return parentId;}

http://chatgpt.dhexx.cn/article/G4WlPhFn.shtml

相关文章

Date转换年月日

timebasic.js //时间戳转年月日 export function format(shijianchuo) {//shijianchuo是整数&#xff0c;否则要parseInt转换var time new Date(shijianchuo);var y time.getFullYear();var m time.getMonth() 1;m m < 10 ? "0" m : m;var d time.getDate…

C# 接口中DateTime类型字段返回年月日格式,去掉时分秒的数据

背景 在我们平时写接口的时候&#xff0c;避免不了这样一个问题&#xff0c;数据库中存的字段类型为datetime,代码中对应的实体类也是DateTime类型的字段&#xff0c;于是在读取数据库内容之后返回的数据也是DateTime类型的值&#xff0c;比如2022-10-24 18:34:56.110&#xf…

vue3-用dayjs将时间戳转为年月日格式

已知&#xff0c;格式化时间&#xff1a;dayjs(cellValue).format(YYYY-MM-DD) 用法&#xff1a; import dayjs from dayjs;dayjs(时间戳).format(YYYY-MM-DD HH:mm:ss); 如&#xff0c;在get请求中使用&#xff1a; service.get(/trace/sourceSearchInput.value).then(res …

Java但中获取时间将时间转换成字符串格式(年月日格式)

一:直接上马拿走&#xff1a; package cn.wyj.one;import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date;/*** 测试时间对象和字符串之间的相互转化* DateFormat抽象类和SimpleDateFormat实现类的使用* author 86155**/public class Demo2…

Excel修改日期格式:日月年-年月日

最近处理数据&#xff0c;遇到需要处理一下日期格式&#xff0c;记一下。。。 1、原格式 2、新建Excel表&#xff0c;复制到表中&#xff0c;选择列&#xff0c;数据-分列&#xff0c;下一步…,选择列格式为“DMY”,点击完成 3、效果(若不成功&#xff0c;可以试一试其他的)

各种加密证书

证书相关知识 PFX文件属于数字证书。pfx数字证书既包含有公钥又包含私钥&#xff0c;cer | crt数字证书只包含公钥。参考 JKS&#xff08;Java Key Store&#xff09;就是利用Java Keytool 工具生成的Keystore文件&#xff0c;JKS文件由公钥和密钥构成&#xff0c;其中的公钥…

公钥,私钥,数字签名,证书

今天&#xff0c;我读到一篇好文章。 它用图片通俗易懂地解释了&#xff0c;"数字签名"&#xff08;digital signature&#xff09;和"数字证书"&#xff08;digital certificate&#xff09;到底是什么。 我对这些问题的理解&#xff0c;一直是模模糊糊…

国密SSL证书保障网站安全

国内很多网站为了网站安全都会部署SSL证书&#xff0c;目前市面上申请到的SSL服务器证书基本都是采用RSA国际算法&#xff0c;市场上80%的SSL服务器证书都是由国外CA尤其是美国为主的CA签发的证书。 网络安全就是国家安全&#xff0c;网络安全的对手也已经不仅仅是黑客&#xf…

构建用于签名/加密双证书测试体系的可执行命令

注意事项 生成证书请求的填写 范例Subject: C CN, ST Beijing, L Beijing, O MSI, OU msi, CN ca, emailAddress cagmssl.com 前面的步骤存在错误&#xff0c;后面改用脚本进行证书生成&#xff0c;阅读时请跳过前面错误的内容 错误的内容 -> 开始 CA 生成私钥 o…

来此加密证书申请,验证,自动部署

之前用certbot, 后来一直不报错, 证书不管用, 就想着干脆直接使用来此加密, 不要中间商了, 就有了直接到来此加密注册之旅 注册地址: 来此加密https://letsencrypt.osfipin.com/user-0408/order/list附上这两年的"战绩" 申请这么多证书主要原因是, 测试域名太多, 一…

加密和数字证书

目录 一 KPI概述二 KPI应用1 内容安全加密2 加密文件3 使用非对称加密对称加密密钥4 非对称加密的缺点5 数字签名6 数字证书7 时钟服务8 私钥使用者认证9 总结附&#xff1a;U盾的工作原理介绍 三 详解公钥、私钥、数字证书的概念1 加密和认证2 公钥和私钥3 证书4 总结5 签名证…

加密解密和CA证书杂记

最近两三个月&#xff0c;断断续续的一直在处理CA证书相关的事情。CA证书本质上也是一种加解密&#xff0c;因此就自然而然的涉及到一些加密和解密的技术&#xff0c;这就让我在了解CA的同时&#xff0c;也对加密和解密有了更进一步的认识和理解。 以下便是一个比较杂&#xff…

证书和加解密

刚进公司&#xff0c;在实习期需要了解很多关于加解密算法和证书相关的东西&#xff0c;我以写博客的方式把我近1个多月了解的东西整理出来传授给大家&#xff0c;大家觉得可以的话请不要吝啬你们的赞。 目录 什么是PKI 证书申请流程 加密与解密 签名认证 数字信封 数字…

HTTPS(对称加密+非对称加密+证书)

目录 1. 加密和解密 HTTPS工作过程 2. 对称加密 3. 对称加密 4. 既然都有非对称加密了,那为啥还要有对称加密 5. 中间人攻击 6. 引入证书 HTTPS 也是一个应用层协议. 是在 HTTP 协议的基础上引入了一个加密层. HTTP 协议内容都是按照文本的方式明文传输的. 这就导致在…

非对称加密与数字证书

文章目录 1 非对称加密2 数字签名3 数字证书4 数字签名和数字证书的区别5 CA 认证中心如何保证权威性6 HTTPS 协议7 HTTPS 与 SSL8 为什么不一直使用HTTPS 1 非对称加密 非对称加密&#xff0c;是指不能从加密密钥推算出解密密钥。加密密钥不需要保密&#xff0c;可以公开&…

安全和加密CA证书

一、介绍 1、为什么要加密 ※ 不加密流量的易受攻击性 ● 密码/数据嗅探 ● 数据操作 ● 验证操作 ● 相当于邮寄明信片 ※ 不安全的传统协议 --明文 ● telnet、FTP、POP3等等&#xff1b;不安全密码 ● http.smtp、…

安全-加密与证书

对称加密 在对称加密中&#xff0c;加密和解密使用的是同一个密钥&#xff0c;即&#xff1a;使用相同的密钥对密文进行加密和解密 比如&#xff1a;A和B&#xff0c;A和B保存同一个密钥&#xff0c;A使用这个密钥对明文进行加密&#xff0c;发送给B&#xff0c;B再使用这个密…

加密、签名、证书的基础概念和流程

常用加密算法类型&#xff1a; 加密算法&#xff1a;对称加密 &#xff08;可逆&#xff09; 常用算法 DES&#xff08;Data Encryption Standard&#xff09;&#xff1a;数据加密标准&#xff0c;速度较快&#xff0c;适用于加密大量数据的场合&#xff1b;&#xff08;已…

ssl证书加密方式有哪些?

SSL证书是HTTP明文协议书升级HTTPS加密协议必需的ca证书。ssl证书主要是通过https加密方式实现网站及用户的安全性。那么&#xff0c;你可知道ssl证书加密方式有哪些&#xff1f;一起来看看。 ssl证书加密方式有哪些 ssl证书加密方式1.Base64位数据加密&#xff08;可加密解密…

RK-MPP硬件编解码库介绍和使用

一、下载RK-MPP硬件编解码库 下载链接&#xff1a;https://github.com/rockchip-linux/mpp 二、RK-MPP库介绍 1、资料来源&#xff1a;MPP 开发参考.pdf 2、MPP说明 MPP&#xff08;Media Process Platform &#xff09;是rk提供的一款硬件编解码库&#xff0c;为用户空间屏蔽…