python-xmind转Excel

1、准备环境:

2、运行代码:

python 复制代码
# !/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
XMind转Excel转换器
支持将XMind思维导图文件转换为Excel表格格式
Python版本要求: 3.9+
"""

import os
import sys
import pandas as pd
from xmindparser import xmind_to_dict
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from datetime import datetime


class XmindToExcelConverter:
    """XMind转Excel转换器主类"""

    def __init__(self):
        self.supported_extensions = ['.xmind', '.XMind']

    def convert_xmind_to_excel(self, xmind_file_path, excel_file_path=None):
        """
        将XMind文件转换为Excel文件
        """
        try:
            # 验证输入文件
            if not os.path.exists(xmind_file_path):
                raise FileNotFoundError(f"XMind文件不存在: {xmind_file_path}")

            file_ext = os.path.splitext(xmind_file_path)[1].lower()
            if file_ext not in self.supported_extensions:
                raise ValueError(f"不支持的文件格式: {file_ext},仅支持 {self.supported_extensions}")

            # 解析XMind文件
            print(f"正在解析XMind文件: {xmind_file_path}")
            xmind_data = xmind_to_dict(xmind_file_path)

            if not xmind_data:
                raise ValueError("XMind文件解析失败,文件可能为空或格式不正确")

            # 提取主题数据
            root_topic = xmind_data[0]['topic']

            # 处理数据并转换为DataFrame
            processed_data = self._process_xmind_data(root_topic)

            # 生成Excel文件路径
            if not excel_file_path:
                base_name = os.path.splitext(os.path.basename(xmind_file_path))[0]
                excel_file_path = os.path.join(
                    os.path.dirname(xmind_file_path),
                    f"{base_name}_converted.xlsx"
                )

            # 保存为Excel文件
            self._save_to_excel(processed_data, excel_file_path)

            return excel_file_path

        except Exception as e:
            raise Exception(f"转换过程中出现错误: {str(e)}")

    def _process_xmind_data(self, topic, level=0, parent_path=None):
        """
        递归处理XMind数据,转换为表格格式
        """
        if parent_path is None:
            parent_path = []

        current_path = parent_path + [topic.get('title', '')]
        results = []

        # 添加当前节点
        row_data = {f'层级_{i + 1}': path for i, path in enumerate(current_path)}
        results.append(row_data)

        # 处理子主题
        child_topics = topic.get('topics', [])
        for child_topic in child_topics:
            child_results = self._process_xmind_data(child_topic, level + 1, current_path)
            results.extend(child_results)

        return results

    def _save_to_excel(self, data, excel_file_path):
        """
        将处理后的数据保存为Excel文件
        """
        if not data:
            raise ValueError("没有数据可以保存")

        # 转换为DataFrame
        df = pd.DataFrame(data)

        # 确保列的顺序正确
        max_level = max([int(col.split('_')[1]) for col in df.columns if col.startswith('层级_')])
        ordered_columns = [f'层级_{i + 1}' for i in range(max_level)]

        # 重新排序列
        df = df.reindex(columns=ordered_columns)

        # 保存Excel文件
        df.to_excel(excel_file_path, index=False, engine='openpyxl')
        print(f"Excel文件已保存: {excel_file_path}")


class XmindConverterGUI:
    """图形用户界面"""

    def __init__(self):
        self.root = tk.Tk()
        self.root.title("XMind转Excel转换器 v1.0")
        self.root.geometry("600x400")
        self.root.resizable(True, True)

        self.converter = XmindToExcelConverter()
        self.setup_ui()

    def setup_ui(self):
        """设置用户界面"""
        # 主框架
        main_frame = ttk.Frame(self.root, padding="20")
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 标题
        title_label = ttk.Label(
            main_frame,
            text="XMind转Excel转换器",
            font=("Arial", 16, "bold")
        )
        title_label.pack(pady=(0, 20))

        # 文件选择区域
        file_frame = ttk.LabelFrame(main_frame, text="文件选择", padding="15")
        file_frame.pack(fill=tk.X, pady=(0, 15))

        # XMind文件选择
        xmind_frame = ttk.Frame(file_frame)
        xmind_frame.pack(fill=tk.X, pady=(0, 10))

        ttk.Label(xmind_frame, text="XMind文件:").pack(side=tk.LEFT)

        self.xmind_path_var = tk.StringVar()
        xmind_entry = ttk.Entry(xmind_frame, textvariable=self.xmind_path_var, width=50)
        xmind_entry.pack(side=tk.LEFT, padx=(10, 5))

        ttk.Button(
            xmind_frame,
            text="浏览...",
            command=self.browse_xmind_file
        ).pack(side=tk.LEFT)

        # Excel文件保存位置
        excel_frame = ttk.Frame(file_frame)
        excel_frame.pack(fill=tk.X)

        ttk.Label(excel_frame, text="保存位置:").pack(side=tk.LEFT)

        self.excel_path_var = tk.StringVar()
        excel_entry = ttk.Entry(excel_frame, textvariable=self.excel_path_var, width=50)
        excel_entry.pack(side=tk.LEFT, padx=(10, 5))

        ttk.Button(
            excel_frame,
            text="浏览...",
            command=self.browse_excel_file
        ).pack(side=tk.LEFT)

        # 转换按钮
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=tk.X, pady=(20, 0))

        self.convert_button = ttk.Button(
            button_frame,
            text="开始转换",
            command=self.start_conversion
        )
        self.convert_button.pack(side=tk.LEFT, padx=(0, 10))

        ttk.Button(
            button_frame,
            text="清除",
            command=self.clear_all
        ).pack(side=tk.LEFT)

        ttk.Button(
            button_frame,
            text="退出",
            command=self.root.quit
        ).pack(side=tk.LEFT)

        # 日志区域
        log_frame = ttk.LabelFrame(main_frame, text="转换日志", padding="10")
        log_frame.pack(fill=tk.BOTH, expand=True, pady=(20, 0))

        self.log_text = tk.Text(log_frame, height=10, wrap=tk.WORD)
        scrollbar = ttk.Scrollbar(log_frame, command=self.log_text.yview)
        self.log_text.configure(yscrollcommand=scrollbar.set)

        self.log_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # 进度条
        self.progress_var = tk.DoubleVar()
        self.progress_bar = ttk.Progressbar(
            main_frame,
            variable=self.progress_var,
            maximum=100
        )
        self.progress_bar.pack(fill=tk.X, pady=(10, 0))

        # 状态标签
        self.status_var = tk.StringVar(value="准备就绪")
        status_label = ttk.Label(main_frame, textvariable=self.status_var)
        status_label.pack(fill=tk.X, pady=(5, 0))

    def browse_xmind_file(self):
        """浏览选择XMind文件"""
        file_path = filedialog.askopenfilename(
            title="选择XMind文件",
            filetypes=[
                ("XMind文件", "*.xmind"),
                ("XMind文件", "*.XMind"),
                ("所有文件", "*.*")
            ]
        )
        if file_path:
            self.xmind_path_var.set(file_path)
            # 自动设置Excel保存路径
            base_name = os.path.splitext(os.path.basename(file_path))[0]
            default_excel_path = os.path.join(
                os.path.dirname(file_path),
                f"{base_name}_converted.xlsx"
            )
            self.excel_path_var.set(default_excel_path)

    def browse_excel_file(self):
        """浏览选择Excel保存位置"""
        file_path = filedialog.asksaveasfilename(
            title="保存Excel文件",
            defaultextension=".xlsx",
            filetypes=[
                ("Excel文件", "*.xlsx"),
                ("所有文件", "*.*")
            ]
        )
        if file_path:
            self.excel_path_var.set(file_path)

    def log_message(self, message):
        """添加日志消息"""
        timestamp = datetime.now().strftime("%H:%M:%S")
        formatted_message = f"[{timestamp}] {message}\n"
        self.log_text.insert(tk.END, formatted_message)
        self.log_text.see(tk.END)
        self.root.update()

    def start_conversion(self):
        """开始转换过程"""
        xmind_path = self.xmind_path_var.get().strip()
        excel_path = self.excel_path_var.get().strip()

        if not xmind_path:
            messagebox.showerror("错误", "请选择XMind文件")
            return

        if not excel_path:
            messagebox.showerror("错误", "请选择Excel保存位置")
            return

        try:
            self.convert_button.config(state=tk.DISABLED)
            self.progress_var.set(10)
            self.status_var.set("正在验证文件...")
            self.log_message("开始转换过程")

            self.progress_var.set(30)
            self.status_var.set("正在解析XMind文件...")
            self.log_message(f"输入文件: {xmind_path}")
            self.log_message(f"输出文件: {excel_path}")

            # 执行转换
            result_path = self.converter.convert_xmind_to_excel(xmind_path, excel_path)

            self.progress_var.set(100)
            self.status_var.set("转换完成")
            self.log_message(f"转换成功! 文件已保存至: {result_path}")

            messagebox.showinfo("成功", f"转换完成!\n文件已保存至:\n{result_path}")

        except Exception as e:
            self.log_message(f"转换失败: {str(e)}")
            self.status_var.set("转换失败")
            messagebox.showerror("错误", f"转换过程中出现错误:\n{str(e)}")

        finally:
            self.convert_button.config(state=tk.NORMAL)

    def clear_all(self):
        """清除所有输入"""
        self.xmind_path_var.set("")
        self.excel_path_var.set("")
        self.log_text.delete(1.0, tk.END)
        self.progress_var.set(0)
        self.status_var.set("准备就绪")

    def run(self):
        """运行GUI"""
        self.root.mainloop()


def main():
    """主函数"""
    print("XMind转Excel转换器 v1.0")
    print("=" * 40)

    if len(sys.argv) > 1:
        # 命令行模式
        if sys.argv[1] in ['-h', '--help']:
            print("用法: python xmind_to_excel.py [XMind文件路径] [Excel保存路径]")
        print("示例: python xmind_to_excel.py test.xmind output.xlsx")
        return

    try:
        # 启动GUI
        app = XmindConverterGUI()
        app.run()
    except KeyboardInterrupt:
        print("\n程序已退出")
    except Exception as e:
        print(f"程序运行错误: {e}")


if __name__ == "__main__":
    main()
相关推荐
令狐掌门3 小时前
python *和**做参数的用法
python·python可变参数
百锦再4 小时前
第5章 所有权系统
运维·git·python·eclipse·go·github·负载均衡
麦麦大数据5 小时前
MacOS 安装Python 3.13【同时保留旧版本】
开发语言·python·macos·python安装
梦想画家9 小时前
基于PyTorch的时间序列异常检测管道构建指南
人工智能·pytorch·python
PythonFun10 小时前
OCR图片识别翻译工具功能及源码
python·ocr·机器翻译
虫师c11 小时前
Python浪漫弹窗程序:Tkinter实现动态祝福窗口教程
python·tkinter·动画效果·gui编程·弹窗效果
卓码软件测评11 小时前
第三方软件测试机构:【“Bug预防”比“Bug发现”更有价值:如何建立缺陷根因分析与流转机制?】
功能测试·测试工具·单元测试·测试用例·压力测试·可用性测试
灯火不休时11 小时前
95%准确率!CNN交通标志识别系统开源
人工智能·python·深度学习·神经网络·cnn·tensorflow
deephub12 小时前
FastMCP 入门:用 Python 快速搭建 MCP 服务器接入 LLM
服务器·人工智能·python·大语言模型·mcp