python xmind轉Excel(puppet洛洛原創)

itread01 2020-11-15 16:15:12
Python excel puppet XMind


需求:將xmind檔案轉為Excel檔案,並新增UI介面操作以降低操作難度。

這個需求一句話就講清楚了,但實際上還需要做很多工作:

1,瞭解Xmind檔案結構

2,提取Xmind檔案分支內容(重點)

3,UI介面(非必要)

一,瞭解Xmind檔案結構

1,xmind檔案形式:樹形分支結構(可以先思考如何提取各分支內容)。

 

 

 

Excel提取為何種形式:主幹與分支連線,用“\”號連線。(瞭解原理後也可以寫成其他你想要的形式)

舉例:

https\Tunnel to含義\Tunnel(隧道),中間實體

https\Tunnel to含義\隱藏:規則-隱藏連線

 

二,提取Xmind檔案分支內容(重點)

那麼如何解析上述為具體的資料結構呢?用“from xmindparser import xmind_to_dict”,用xmindparser包將其轉化為字典格式再做處理。

再舉個例子:

 

 

這個xmind檔案通過xmind_to_dict可以轉換為什麼樣呢?

{'title': 'A', 'topics': [{'title': 'B1'}, {'title': 'B2', 'topics': [{'title': 'C1'}, {'title': 'C2'}]}, {'title': 'B3'}]}

還是不夠直觀,用json分析器展開再看:

[
  {
    'title': '畫布 1',
    'topic': {
      'title': 'A',
      'topics': [
        {
          'title': 'B1'
        },
        {
          'title': 'B2',
          'topics': [
            {
              'title': 'C1'
            },
            {
              'title': 'C2'
            }
          ]
        },
        {
          'title': 'B3'
        }
      ]
    },
    'structure': 'org.xmind.ui.map.unbalanced'
  }
]

 

內容裝在一個list裡,字典最外層title為“畫布1”,topic裝有我們需要的內容(可以看出其他位置叫topics),這是xmind檔案中沒有的,經驗證這是個固定值,可以忽略。然後通過取list,A是字典中value值,key為title,其子節點裝在topics的分支中。處理後是這樣,最外層是dict:

 

 那麼問題來了,如何將其處理為想要的形式呢?一層層的取key、value嗎?

當然不是,那工作量將非常龐大,而且不利於閱讀和修改。還記得剛才的思考內容嗎?這裡我們就需要用到你所想的,沒錯,遞迴。

為什麼要用遞迴,我們仔細看看結構:

A的三個子節點分別為B1,B2,B3,B2 的子節點為C1C2,參看上圖你想到了什麼?

1,標題和子節點放在不同的item裡,即topic放根節點,那topics則放其子節點。

2,topics無子節點呢?像C1C2那樣的點沒有子節點,我們發現,它也沒有topics;同時,沒有子節點證明它是這條分支的最後一層了;試想,如果A沒子節點,就只有它一個呢?正如你所想,它只有一個title,沒有topics。

3,A的子節點是一個list,list可以有多個子節點,子節點若還有子節點則有topics,若沒有則沒有topics。

4,title永遠裝的是string,而topics可以裝list,list裡還有dict,也可以沒有topics。

看了四點還是覺得很亂?

我們需要一層層取子節點才可以得到我們想要的A\B2\C1、A\B2\C2,節點值永遠在title裡,而子節點卻在dict、list裡的dict裡,而且子節點裡有的只有一個title,有的有一個title加一個topics,前文已經說過,有topics的是還有其子節點的。

那麼現在應該清晰點了吧?還不清楚?那虛擬碼再來一遍:

如果 輸入字典:

當字典只有有title時:

操作1

當字典有title和topics時:

操作2

如果 輸入list:

遍歷list裡的字典:

對每個字典進行操作3

如果 輸入的既不是字典也不是list:

輸出值

 

 

思路框架已經搭建了,那操作1、2、3是什麼呢?其實就是本框架的重複操作,呼叫下自己就可以了,不嚴謹的說這就是遞迴的通俗解釋。

我們貼下程式碼:

 1 def TraversalXmind(root,rootstring):
2 if isinstance(root, dict):
3 if len(root) == 2:
4 TraversalXmind(root['topics'], str(rootstring) )
5 if len(root) == 1:
6 TraversalXmind(root['title'],str(rootstring) )
7
8 elif isinstance(root, list):
9 for sonroot in root:
10 TraversalXmind(sonroot, str(rootstring) + "\\" + sonroot['title'])
11
12 elif isinstance(root,str):
13 print(str(rootstring) )
14
15 # TraversalXmind(root, "\\AA")

  完整程式碼是什麼呢?

將上述轉換過程解除安裝model.py中:

 1 # -*-coding:utf-8 -*-
2 # Author : zhengyong
3 # Time : 2020/11/5 23:06
4 # FileName: model.py
5
6 from xmindparser import xmind_to_dict
7 import os,csv
8 # filepath1 = os.path.abspath(os.path.dirname(__file__))
9 # print(filepath1)
10
11 # filepath = "D:\\test.xmind"
12 # inputedXmind = xmind_to_dict(filepath)
13 # root = inputedXmind[0]['topic']
14
15 def traversalXmind(root, rootstring,lisitcontainer):
16 """
17 功能:遞迴dictionary檔案得到容易寫入Excel形式的格式。
18 注意:rootstring都用str來處理中文字元
19 @param root: 將xmind處理後的dictionary檔案
20 @param rootstring: xmind根標題
21 """
22 if isinstance(root, dict):
23 if len(root) == 2:
24 traversalXmind(root['topics'], str(rootstring),lisitcontainer)
25 if len(root) == 1:
26 traversalXmind(root['title'], str(rootstring),lisitcontainer)
27
28 elif isinstance(root, list):
29 for sonroot in root:
30 traversalXmind(sonroot, str(rootstring) + "\\" + sonroot['title'],lisitcontainer)
31
32 elif isinstance(root, str):
33 lisitcontainer.append(str(rootstring))
34
35 def getCase(root):
36 rootstring = root['title']
37 lisitcontainer = []
38 traversalXmind(root, rootstring,lisitcontainer)
39 # print(lisitcontainer)
40 return lisitcontainer
41
42 # def getTestCase(filename,lisitcontainer,directory,group,runType,testcaseType,testType):
43 # header = [
44 # '測試案例路徑',
45 # '測試案例名稱',
46 # '測試案例描述',
47 # '計劃執行時長(分鐘)',
48 # '步驟描述',
49 # '預期結果',
50 # '優先順序',
51 # '小組',
52 # '執行方式',
53 # '測試模組',
54 # '版本號',
55 # '用例型別',
56 # '測試型別',
57 # '關聯故事卡片ID',
58 # ]
59 #
60 # with open(filename,'w',newline='') as f:
61 # writer = csv.DictWriter(f,fieldnames=header),
62 # writer.writeheader()
63 # for row in lisitcontainer:
64 # writer.writerow({
65 # '測試案例路徑': directory,
66 # '測試案例名稱': row,
67 # '小組': group,
68 # '執行方式': runType,
69 # '用例型別':testcaseType,
70 # '測試型別': testType,
71 # })

 

三,UI介面

UI介面用tkinter寫的,直接上程式碼:

 1 #-*-coding:utf-8 -*-
2 # Author : zhengyong
3 # Time : 2020/11/14 23:54
4 # FileName: main1.py
5 # https://github.com/ndnmonkey/transXmindToCSV.git
6
7 import model
8 from xmindparser import xmind_to_dict
9 import tkinter
10 from tkinter import filedialog
11 from tkinter import *
12 import os,csv
13
14
15 window = tkinter.Tk()
16 window.title("用例匯出工具")
17 # 設定視窗圖示
18 # window.iconbitmap("D:\Code\Python\XmindToExcel\image\icon.ico")
19 # window.iconbitmap("image\ifavicon.ico")
20 window.geometry("400x370+200+50")
21
22 # 標題
23 labeltitle = tkinter.Label(window,text = "用例匯出工具",font = ('幼圓',20)).pack()
24
25 # 建立選單欄
26 MenuBar = tkinter.Menu(window)
27 # 將選單欄放到主視窗
28 window.config(menu=MenuBar)
29 # 建立檔案選單,不顯示分窗
30 fileBar = tkinter.Menu(MenuBar, tearoff=0)
31 # 新增檔案選單項
32 fileBar.add_command(label="用法說明")
33 # fileBar.add_command(label="聯絡作者")
34 # 建立分割線
35 # fileBar.add_separator()
36 fileBar.add_command(label="退出", command=window.destroy)
37 # 將檔案選單新增到選單欄
38 MenuBar.add_cascade(label="選單", menu=fileBar)
39
40 xlabe = 20
41 xtext = 80
42 y =10
43 step = 30
44 textwidth = 250
45
46 inputtext1 = tkinter.StringVar(value='\常規版本用例\當前版本名\姓名\需求名')
47 labe1 = tkinter.Label(window, text='用例路徑:').place(x=xlabe,y = y + step)
48 text1 = tkinter.Entry(window, show=None, textvariable=inputtext1)
49 text1.place(width=textwidth,x=xtext+ 1*step,y=y + step)
50
51 inputtext2 = tkinter.StringVar(value='小組長姓名')
52 labe2 = tkinter.Label(window, text='組長姓名:').place(x=xlabe,y=y + 2*step)
53 text2 = tkinter.Entry(window, show=None, textvariable=inputtext2)
54 text2.place(width=textwidth,x=xtext+ 1*step,y=y + 2*step)
55
56 inputtext3 = tkinter.StringVar(value='手工測試')
57 labe3 = tkinter.Label(window, text='執行方式:').place(x=xlabe,y=y + 3*step)
58 text3 = tkinter.Entry(window, show=None, textvariable=inputtext3)
59 text3.place(width=textwidth,x=xtext+ 1*step,y=y + 3*step)
60
61 inputtext4 = tkinter.StringVar(value='系統用例')
62 labe4 = tkinter.Label(window, text='用例型別:').place(x=xlabe,y=y + 4*step)
63 text4 = tkinter.Entry(window, show=None, textvariable=inputtext4)
64 text4.place(width=textwidth,x=xtext+ 1*step,y=y + 4*step)
65
66 inputtext5 = tkinter.StringVar(value='手工測試')
67 labe5 = tkinter.Label(window, text='測試型別:').place(x=xlabe,y=y + 5*step)
68 text5 = tkinter.Entry(window, show=None, textvariable=inputtext5)
69 text5.place(width=textwidth,x=xtext+ 1*step,y=y + 5*step)
70
71 def getTextValues():
72 templist = []
73 var1 = text1.get();templist.append(var1)
74 var2 = text2.get();templist.append(var2)
75 var3 = text3.get();templist.append(var3)
76 var4 = text4.get();templist.append(var4)
77 var5 = text5.get();templist.append(var5)
78 # print("1",templist)
79 return templist
80
81 casebutton1 = tkinter.Button(window,text = '1,提交用例資訊',width=5,height=1,command=getTextValues)
82 casebutton1.place(x=110,y=y + 6*step)
83 casebutton1.configure(width = 34, height = 2)
84
85 def open_file():
86 templist = getTextValues()
87 # print("2",templist)
88 filename = filedialog.askopenfilename(title='開啟Xmind檔案', filetypes=[('xmind', '*.xmind')])
89
90 entry_filename.delete(0, END)
91 entry_filename.insert('insert', filename)
92 # print(entry_filename,type(entry_filename))
93
94 # print(filename)
95 fname = entry_filename.get() #用get提取entry中的內容
96 fname = str(fname).replace('/','\\\\')
97 # print("fname",fname)
98
99 # filepath = "D:\\test.xmind"
100 # inputedXmind = xmind_to_dict(filepath)
101 # root = inputedXmind[0]['topic']
102 #
103 inputedXmind = xmind_to_dict(fname)
104 root = inputedXmind[0]['topic']
105 lisitcontainer = model.getCase(root)
106 # print(lisitcontainer)
107
108 # templist
109 directory = templist[0]
110 group = templist[1]
111 runType = templist[2]
112 testcaseType = templist[3]
113 testType = templist[4]
114 # filename = 'testcase.csv'
115 header = [
116 '測試案例路徑',
117 '測試案例名稱',
118 '測試案例描述',
119 '計劃執行時長(分鐘)',
120 '步驟描述',
121 '預期結果',
122 '優先順序',
123 '小組',
124 '執行方式',
125 '測試模組',
126 '版本號',
127 '用例型別',
128 '測試型別',
129 '關聯故事卡片ID',
130 ]
131 # print(filename) #D:\\test.xmind
132 savepath = fname.split('.')[0] + ".csv"
133 # print("savepath:",savepath)
134
135 with open(savepath, 'w', newline='') as f:
136 writer = csv.DictWriter(f, fieldnames=header)
137 writer.writeheader()
138 for row in lisitcontainer:
139 writer.writerow({
140 '測試案例路徑': directory,
141 '測試案例名稱': row,
142 '小組': group,
143 '執行方式': runType,
144 '用例型別': testcaseType,
145 '測試型別': testType,
146 })
147
148 # 設定button按鈕接受功能
149 importbutton = tkinter.Button(window, text="2,匯入Xmind檔案", command=open_file)
150 importbutton.place(x=110,y=y + 9*step)
151 importbutton.configure(width =34,height=2)
152
153 # 設定entry
154 entry_filename = tkinter.Entry(window, width=30, font=("宋體", 10, 'bold'))
155 entry_filename.place(width=textwidth,x=xtext+ 1*step,y=y + 8*step)
156
157 # 版權頁
158 labelright = tkinter.Label(window,text = "version 0.3 bug修復:[email protected]",font = ('宋體',8)).place(x=60,y=350)
159 # Tk().iconbitmap('D:\Code\Python\XmindToExcel\image\icon.ico')
160 window.mainloop()

那麼這時候還有一個問題,執行之後的結果是什麼?

 

 用pyinstaller就可以打包程式碼檔案變成可執行檔案:

方法:

1,安裝pyinstaller(不具體介紹)

2,使用:

命令列:

pyinstaller -F 主檔名.py

執行可執行檔案有黑框怎麼辦?

pyinstaller -F -w mycode.py (-w就是取消視窗)

3,生成的可執行檔案在哪?

在主檔案同級資料夾dist中,

4,具體檔案結構:

 

 四,宣告

所有程式碼均為原創,因為實在找不到可用的教程,瞭解到找教程的艱辛,所以拋磚引玉,本人水平有限,如果文章和程式碼有表述不當之處,還請不吝賜教,可以交流討論。

歡迎轉載,請註明以下內容:

本人在cnblogs上的ID為puppet洛洛,部落格地址為https://www.cnblogs.com/two-peanuts/所有包含原創宣告的部落格均為本人原創作品。部落格的內容除已註明的引用文獻外均為本人獨立研究成果。除特殊註明外均採用 知識共享 署名-非商業性使用-相同方式共享 3.0 中國大陸 許可協議進行許可。

五,github地址

具體的檔案結構已傳至github,github地址:https://github.com/ndnmonkey/transXmindToCSV ,歡迎star。

&n

版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://www.itread01.com/content/1605427446.html

  1. 利用Python爬虫获取招聘网站职位信息
  2. Using Python crawler to obtain job information of recruitment website
  3. Several highly rated Python libraries arrow, jsonpath, psutil and tenacity are recommended
  4. Python装饰器
  5. Python实现LDAP认证
  6. Python decorator
  7. Implementing LDAP authentication with Python
  8. Vscode configures Python development environment!
  9. In Python, how dare you say you can't log module? ️
  10. 我收藏的有关Python的电子书和资料
  11. python 中 lambda的一些tips
  12. python中字典的一些tips
  13. python 用生成器生成斐波那契数列
  14. python脚本转pyc踩了个坑。。。
  15. My collection of e-books and materials about Python
  16. Some tips of lambda in Python
  17. Some tips of dictionary in Python
  18. Using Python generator to generate Fibonacci sequence
  19. The conversion of Python script to PyC stepped on a pit...
  20. Python游戏开发,pygame模块,Python实现扫雷小游戏
  21. Python game development, pyGame module, python implementation of minesweeping games
  22. Python实用工具,email模块,Python实现邮件远程控制自己电脑
  23. Python utility, email module, python realizes mail remote control of its own computer
  24. 毫无头绪的自学Python,你可能连门槛都摸不到!【最佳学习路线】
  25. Python读取二进制文件代码方法解析
  26. Python字典的实现原理
  27. Without a clue, you may not even touch the threshold【 Best learning route]
  28. Parsing method of Python reading binary file code
  29. Implementation principle of Python dictionary
  30. You must know the function of pandas to parse JSON data - JSON_ normalize()
  31. Python实用案例,私人定制,Python自动化生成爱豆专属2021日历
  32. Python practical case, private customization, python automatic generation of Adu exclusive 2021 calendar
  33. 《Python实例》震惊了,用Python这么简单实现了聊天系统的脏话,广告检测
  34. "Python instance" was shocked and realized the dirty words and advertisement detection of the chat system in Python
  35. Convolutional neural network processing sequence for Python deep learning
  36. Python data structure and algorithm (1) -- enum type enum
  37. 超全大厂算法岗百问百答(推荐系统/机器学习/深度学习/C++/Spark/python)
  38. 【Python进阶】你真的明白NumPy中的ndarray吗?
  39. All questions and answers for algorithm posts of super large factories (recommended system / machine learning / deep learning / C + + / spark / Python)
  40. [advanced Python] do you really understand ndarray in numpy?
  41. 【Python进阶】Python进阶专栏栏主自述:不忘初心,砥砺前行
  42. [advanced Python] Python advanced column main readme: never forget the original intention and forge ahead
  43. python垃圾回收和缓存管理
  44. java调用Python程序
  45. java调用Python程序
  46. Python常用函数有哪些?Python基础入门课程
  47. Python garbage collection and cache management
  48. Java calling Python program
  49. Java calling Python program
  50. What functions are commonly used in Python? Introduction to Python Basics
  51. Python basic knowledge
  52. Anaconda5.2 安装 Python 库(MySQLdb)的方法
  53. Python实现对脑电数据情绪分析
  54. Anaconda 5.2 method of installing Python Library (mysqldb)
  55. Python implements emotion analysis of EEG data
  56. Master some advanced usage of Python in 30 seconds, which makes others envy it
  57. python爬取百度图片并对图片做一系列处理
  58. Python crawls Baidu pictures and does a series of processing on them
  59. python链接mysql数据库
  60. Python link MySQL database