自己编写的MyXMindUtils(XMind转json串)

对应XMind的读入,注释写的挺详细了,不懂评论即可,作者常年蹲在csdn。现在的utils兼容XMind8和ProcessOn下载的XMind。目前在写XMind的jar包

pom.xml:

<!--Xmind -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-compress</artifactId>
            <version>1.20</version>
        </dependency>
        <dependency>
            <groupId>com.github.eljah</groupId>
            <artifactId>xmindjbehaveplugin</artifactId>
            <version>0.8</version>
        </dependency>

model:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class XMindNodeModel implements Serializable {
    String content;
    String comment;
    Set<String> labels;
    Set<String> markers;
    String link;
    Integer level;
    String iImage;

    List<XMindNodeModel> children;

    public enum ColumnEnum{
        content,
        comment,
        labels,
        markers,
        link,
        level,
        iImage;
    }
}

utils:

@Slf4j
public class MyXMindUtils {

    public static final String CONTENT_JSON = "content.json";
    //当前文件位置
    private static final String CURRENT_PATH = System.getProperty("user.dir");

    /**
     * 想读XMind,读就完了
     * */
    public static Object readXMind(File file) {
        String res = null;
        Object contents = null;
        try {
            res = extract(file);
            if (isXMindNetwork(res, file)) {
                contents = (getXMindNetworkContent(file, res));
            } else {
                contents = getXMind8Content(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 删除生成的文件夹
            if (res != null) {
                File dir = new File(res);
                deleteDir(dir);
            }
            // 删除零时文件
//            if (file != null) {
//                file.delete();
//            }
        }
        return contents;
    }

    /**
     * 填充节点
     *
     * @param iTopic
     * @return 一个节点
     */
    public static XMindNodeModel fillNode(ITopic iTopic) {
        XMindNodeModel newNode = new XMindNodeModel();
        try {
            //内容
            newNode.setContent(iTopic.getTitleText());
            //链接
            newNode.setLink(iTopic.getHyperlink());
            //标签
            Set<String> labels = iTopic.getLabels();
            if (labels != null && labels.size() != 0) {
                newNode.setLabels(labels);
            }
            //图片
            //IImage image = iTopic.getImage();
            //newNode.setIImage(image.getSource());
            //批注
            //newNode.setMarkers();
            //备注
            IPlainNotesContent content = (IPlainNotesContent) iTopic.getNotes().getContent(INotes.PLAIN);
            if (content != null) {
                newNode.setComment(content.getTextContent());
            }
        } catch (Exception e) {
            log.error("*****填充node出错*****");
            e.printStackTrace();
        }

        return newNode;
    }

    /**
     * 填充节点
     *
     * @param attachedObject
     * @return 一个节点
     */
    public static XMindNodeModel fillNodeNetwork(JSONObject attachedObject) {
        XMindNodeModel newNode = new XMindNodeModel();
        try {
            JSONObject notes = attachedObject.getJSONObject("notes");
            if (notes != null) {
                JSONObject plain = notes.getJSONObject("plain");
                if (plain != null) {
                     newNode.setComment(plain.getString("content"));
                }
            }
            newNode.setContent(attachedObject.getString("title"));
            newNode.setLabels(Collections.singleton(attachedObject.getString("labels")));
            newNode.setMarkers(Collections.singleton(attachedObject.getString("markers")));
        } catch (Exception e) {
            log.error("*****填充nodeNetwork出错*****");
            e.printStackTrace();
        }
        return newNode;
    }

    /**
     * 建立文件内容树
     *
     * @param file
     * @return json串
     */
    public static Object getXMind8Content(File file) {
        //初始化builder
        IWorkbookBuilder builder = Core.getWorkbookBuilder();
        IWorkbook workbook = null;
        try {
            //打开XMind文件
            workbook = builder.loadFromFile(file, new ByteArrayStorage(), null);
        } catch (IOException | CoreException e) {
            e.printStackTrace();
        }

        if (workbook==null){
            return "文件为空或格式不匹配";
        }

        //获取主Sheet
        ISheet defSheet = workbook.getPrimarySheet();
        //获取根Topic
        ITopic rootTopic = defSheet.getRootTopic();
        //遍历树
        Queue<Object> iTopicQueue = new LinkedList<>();
        iTopicQueue.add(rootTopic);
        //新树
        XMindNodeModel xMindNodeRoot = new XMindNodeModel();
        xMindNodeRoot.setContent(rootTopic.getTitleText());
        xMindNodeRoot.setLevel(1);
        iTopicQueue.add(xMindNodeRoot);
        while (!iTopicQueue.isEmpty()) {
            ITopic oldTreeNode = (ITopic) iTopicQueue.poll();
            XMindNodeModel treeNode = (XMindNodeModel) iTopicQueue.poll();
            if (treeNode == null) {
                return null;
            }
            Integer level = treeNode.getLevel() + 1;
            List<XMindNodeModel> xMindNodeModels = new ArrayList<>();
            for (ITopic oneChild: oldTreeNode.getAllChildren()) {
                XMindNodeModel newNode = MyXMindUtils.fillNode(oneChild);
                newNode.setLevel(level);
                xMindNodeModels.add(newNode);
                iTopicQueue.add(oneChild);
                iTopicQueue.add(newNode);
            }
            treeNode.setChildren(xMindNodeModels);
        }
        return JSON.toJSON(xMindNodeRoot);
    }

    /**
     * 网上版本 建立文件内容树
     *
     * @param file
     * @return json串
     */
    public static Object getXMindNetworkContent(File file, String extractFileDir)
            throws IOException {
        List<String> keys = new ArrayList<>();
        keys.add(CONTENT_JSON);
        Map<String, String> map = getContents(keys, file, extractFileDir);
        String content = map.get(CONTENT_JSON);
        JSONArray jsonArray = JSONArray.parseArray(content);
        JSONObject jsonObject = (JSONObject) jsonArray.get(0);
        JSONObject rootTopic = jsonObject.getJSONObject("rootTopic");

        //遍历树
        Queue<Object> iTopicQueue = new LinkedList<>();
        iTopicQueue.add(rootTopic);
        //新树
        XMindNodeModel xMindNodeRoot = new XMindNodeModel();
        xMindNodeRoot.setContent(rootTopic.getString("title"));
        xMindNodeRoot.setLevel(1);
        iTopicQueue.add(xMindNodeRoot);
        while(!iTopicQueue.isEmpty()){
            JSONObject oldTreeNode = (JSONObject) iTopicQueue.poll();
            XMindNodeModel treeNode = (XMindNodeModel) iTopicQueue.poll();
            if (treeNode == null) {
                return null;
            }
            Integer level = treeNode.getLevel() + 1;
            List<XMindNodeModel> xMindNodeModels = new ArrayList<>();
            JSONObject children = oldTreeNode.getJSONObject("children");
            if(children == null){
                continue;
            }
            JSONArray attachedArray = children.getJSONArray("attached");
            if (attachedArray == null) {
                continue;
            }
            for (Object attached : attachedArray) {
                JSONObject attachedObject = (JSONObject) attached;
                XMindNodeModel newNode = MyXMindUtils.fillNodeNetwork(attachedObject);
                newNode.setLevel(level);
                xMindNodeModels.add(newNode);
                iTopicQueue.add(attachedObject);
                iTopicQueue.add(newNode);
            }
            treeNode.setChildren(xMindNodeModels);
        }
        return JSON.toJSON(xMindNodeRoot);
    }

    /**
     *判断是否有CONTENT_JSON文件
     *
     * */
    private static boolean isXMindNetwork(String res, File file) {
        // 解压
        File parent = new File(res);
        if (parent.isDirectory()) {
            String[] files = parent.list(new FileFilter());
            for (int i = 0; i < Objects.requireNonNull(files).length; i++) {
                if (files[i].equals(CONTENT_JSON)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 返回解压后的文件夹名字
     *
     */
    public static String extract(File file) throws IOException, ArchiveException {
        Expander expander = new Expander();
        String destFileName = CURRENT_PATH + File.separator + "XMind" + System.currentTimeMillis();
        expander.expand(file, new File(destFileName));
        return destFileName;
    }

    /**
     * 找CONTENT_JSON文件
     *
     * */
    public static Map<String, String> getContents(List<String> subFileNames, File file, String extractFileDir)
            throws IOException {
        String destFilePath = extractFileDir;
        Map<String, String> map = new HashMap<>(16);
        File destFile = new File(destFilePath);
        if (destFile.isDirectory()) {
            String[] res = destFile.list(new FileFilter());
            for (int i = 0; i < Objects.requireNonNull(res).length; i++) {
                if (subFileNames.contains(res[i])) {
                    String s = destFilePath + File.separator + res[i];
                    String content = getFileContent(s);
                    map.put(res[i], content);
                }
            }
        }
        return map;
    }

    /**
     * 返回CONTENT_JSON文件内容
     *
     * */
    public static String getFileContent(String fileName) throws IOException {
        File file;
        try {
            file = new File(fileName);
        } catch (Exception e) {
            throw new RuntimeException("找不到该文件");
        }
        FileReader fileReader = new FileReader(file);
        BufferedReader bufferedReder = new BufferedReader(fileReader);
        StringBuilder stringBuffer = new StringBuilder();
        while (bufferedReder.ready()) {
            stringBuffer.append(bufferedReder.readLine());
        }
        // 打开的文件需关闭,在unix下可以删除,否则在windows下不能删除(file.delete())
        bufferedReder.close();
        fileReader.close();
        return stringBuffer.toString();
    }

    /**
     * 过滤器
     */
    static class FileFilter implements FilenameFilter {
        @Override
        public boolean accept(File dir, String name) {
            // String的 endsWith(String str)方法 筛选出以str结尾的字符串
            if (name.endsWith(".xml") || name.endsWith(".json")) {
                return true;
            }
            return false;
        }
    }

    /**
     * 删除生成的文件夹
     */
    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            // 递归删除目录中的子目录下
            for (int i = 0; i < children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空,可以删除
        return dir.delete();
    }
}

使用方式:

@SpringBootTest
public class XmindTests {

    @Test
    public void Xmind() {
        File file = new File("C:\\Users\\Desktop\\xxx.xmind");
        System.out.println(MyXMindUtils.readXMind(file));
    }
}

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心脏dance

如果解决了您的疑惑,谢谢打赏呦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值