紀錄輸出訊息至 Excel
由於客戶會不定期得要求我們提供資料(俗稱ChangeNote)讓他們檢視目前專案進行的情況,其中最重要的一部分就是這段時間修改了哪些程式碼、修復了哪些Bug。雖然這些資料只需透過Git相關指令即可取得,但顯示在終端機的樣子實在不是很好看,還是要整理成表格才能交給客戶觀賞,因此泰勞就寫了一個簡單的Python腳本來幫我完成這件事!
參考資料:
https://github.com/python-excel/xlwt
Get the output of system command as a string in python - StackOverflow
網路上找到了一個很好用的模組-xlwt,可以用來將資料寫入Excel檔案。在使用它之前必須先透過以下指令來安裝。
可能有些人安裝時會遇到一些問題,如下圖所示。
通常看到Permission denied都會想到在指令前面加上sudo,確實是可以解決問題,但在我上網搜尋解答時,剛好看到一篇蠻重要的討論,作者建議不要使用sudo,取而代之的是在指令後面加上--user參數,如下所示。
安裝好xlwt之後就開始來寫Python腳本吧!先來練習將一些簡單的資料寫進一個Excel檔案,如下所示。
接著執行此腳本就會出現一個名為example的Excel檔案,打開來會看到一個名為Sheet1的分頁,裡面存放了兩筆資料。
很簡單吧!接著嘗試將List裡面的值透過for迴圈依依寫入!
此時表格裡面的第一行會是List a的資料,第二行會是List b的資料,如圖所示。
有沒有覺得很有趣呢?再來練習稍微複雜一點的,嘗試在腳本裡面執行一個簡單的指令,並且把輸出的訊息紀錄至檔案裡面。
執行後會印出兩次text,主要目的為除錯,方便自己查看目前text物件的狀態。第一次印出來的是系統輸出的訊息的原始樣子,第二次印出的是經過換行符號來區分的List。
打鐵要趁熱、打劫要趁三更半夜、打Game要趁老闆不在、打小孩要趁四下無人、打老婆......,不行打老婆(比司吉會變身)。總之,把指令的複雜度再稍微提高,把"ls"改成"ls -l",讓輸出的訊息更複雜一些。
用巢狀迴圈讓輸出的訊息先以列為基準分開,再將每一列的內容以空白部份為基準分開,讓每一筆資料都單獨存放於一個欄位,使生成的表格更容易閱讀。
現在已經學會如何紀錄輸出訊息至Excel檔案了,回歸一開始的正題:將修改紀錄輸出至Excel檔案,就如同上面的方法,只要將欲執行的指令改成我要的,然後加入一些欄位標題即可生成一份[簡約]的ChangeNote!
另外,也許有些人會有這樣的需求,為了方便大家閱讀,某些文件會有固定的格式,所以需要將固定的格式匯入至新的檔案,再將資料依依寫入,這要怎麼做呢?此時只要使用兩個好用的模組-xlrd與xlutils.copy即可達成上述條件,如下範例所示。
註:
如果終端輸出的資料『長的很整齊』的話,就不需要搞的這麼複雜,因為CSV格式的檔案支援以逗號或空白分隔的資料,當選用Excel開啟副檔名為CSV的檔案,做些簡單的設定即可讓資料完美呈現喔,來看看下面的範例吧!
接著選用Excel開啟example.csv,並且選擇以逗號分隔,結果呈現如圖所示。
當然,直接將輸出放入CSV還是有些缺點的,像是它無法處理多行或有換行的字串,這會造成格式跑掉,也不能針對內容做修改或是調整欄位之類的需求。
GitHub:
https://github.com/Kuanlin-Chen/ChangeNote
參考資料:
https://github.com/python-excel/xlwt
Get the output of system command as a string in python - StackOverflow
網路上找到了一個很好用的模組-xlwt,可以用來將資料寫入Excel檔案。在使用它之前必須先透過以下指令來安裝。
$ pip install xlwt
可能有些人安裝時會遇到一些問題,如下圖所示。
$ pip install xlwt --user
安裝好xlwt之後就開始來寫Python腳本吧!先來練習將一些簡單的資料寫進一個Excel檔案,如下所示。
#!/usr/bin/env python
"""
Program:
This program will record log into Excel.
History:
20170707 Kuanlin Chen
"""
#匯入模組(Module)
import sys
import xlwt
#建立Workbook物件
book = xlwt.Workbook(encoding="utf-8")
#使用Workbook裡的add_sheet函式來建立Worksheet
sheet1 = book.add_sheet("Sheet1")
def main(orig_args):
filename = "example.xls"
output(filename)
def output(filename):
#使用Worksheet裡的write函式將值寫入
sheet1.write(0,0,'AAA')
sheet1.write(0,1,'BBB')
#將Workbook儲存為原生Excel格式的檔案
book.save(filename)
if __name__ == '__main__':
main(sys.argv)
"""
Program:
This program will record log into Excel.
History:
20170707 Kuanlin Chen
"""
#匯入模組(Module)
import sys
import xlwt
#建立Workbook物件
book = xlwt.Workbook(encoding="utf-8")
#使用Workbook裡的add_sheet函式來建立Worksheet
sheet1 = book.add_sheet("Sheet1")
def main(orig_args):
filename = "example.xls"
output(filename)
def output(filename):
#使用Worksheet裡的write函式將值寫入
sheet1.write(0,0,'AAA')
sheet1.write(0,1,'BBB')
#將Workbook儲存為原生Excel格式的檔案
book.save(filename)
if __name__ == '__main__':
main(sys.argv)
接著執行此腳本就會出現一個名為example的Excel檔案,打開來會看到一個名為Sheet1的分頁,裡面存放了兩筆資料。
def output(filename):
a = ['c', 'd', 'e', 'f', 'g']
b = [123, 456, 789]
i = 0
for word in a:
sheet1.write(i,0,word)
i = i+1
j = 0
for num in b:
sheet1.write(j,1,num)
j = j+1
book.save(filename)
a = ['c', 'd', 'e', 'f', 'g']
b = [123, 456, 789]
i = 0
for word in a:
sheet1.write(i,0,word)
i = i+1
j = 0
for num in b:
sheet1.write(j,1,num)
j = j+1
book.save(filename)
此時表格裡面的第一行會是List a的資料,第二行會是List b的資料,如圖所示。
#要多匯入這兩個Module
import subprocess
import string
def output(filename):
proc = subprocess.Popen('ls',stdout=subprocess.PIPE)
text = proc.stdout.read()
print(text) #除錯用
text = text.split('\n')
print(text) #除錯用
i = 0
for word in text:
sheet1.write(i,0,word)
i = i+1
book.save(filename)
import subprocess
import string
def output(filename):
proc = subprocess.Popen('ls',stdout=subprocess.PIPE)
text = proc.stdout.read()
print(text) #除錯用
text = text.split('\n')
print(text) #除錯用
i = 0
for word in text:
sheet1.write(i,0,word)
i = i+1
book.save(filename)
執行後會印出兩次text,主要目的為除錯,方便自己查看目前text物件的狀態。第一次印出來的是系統輸出的訊息的原始樣子,第二次印出的是經過換行符號來區分的List。
def output(filename):
#另一種方式
#proc = subprocess.Popen('ls -l',shell=True,stdout=subprocess.PIPE)
proc = subprocess.Popen(['ls','-l'],stdout=subprocess.PIPE)
text = proc.stdout.read()
text = text.split('\n')
i = 0
for line in text:
#split方法若不帶入參數,會以空白部份分隔
line = line.split()
print(line) #除錯用
j = 0
for word in line:
sheet1.write(i,j,word)
j = j+1
i = i+1
book.save(filename)
#另一種方式
#proc = subprocess.Popen('ls -l',shell=True,stdout=subprocess.PIPE)
proc = subprocess.Popen(['ls','-l'],stdout=subprocess.PIPE)
text = proc.stdout.read()
text = text.split('\n')
i = 0
for line in text:
#split方法若不帶入參數,會以空白部份分隔
line = line.split()
print(line) #除錯用
j = 0
for word in line:
sheet1.write(i,j,word)
j = j+1
i = i+1
book.save(filename)
用巢狀迴圈讓輸出的訊息先以列為基準分開,再將每一列的內容以空白部份為基準分開,讓每一筆資料都單獨存放於一個欄位,使生成的表格更容易閱讀。
另外,也許有些人會有這樣的需求,為了方便大家閱讀,某些文件會有固定的格式,所以需要將固定的格式匯入至新的檔案,再將資料依依寫入,這要怎麼做呢?此時只要使用兩個好用的模組-xlrd與xlutils.copy即可達成上述條件,如下範例所示。
import sys
import xlwt
import xlrd
import xlutils.copy
try:
#將範本打開
inbook = xlrd.open_workbook('sample.xls', formatting_info=True)
#複製給outbook物件
outbook = xlutils.copy.copy(inbook)
#取得分頁並將字串寫入座標為(5,5)的欄位
#預設是不能複寫欄位裡的資料喔!
outbook.get_sheet(0).write(5,5,"ILoveBaseball")
#若儲存為同樣的檔名會出現Permission denied的錯誤訊息喔!
outbook.save('mynote.xls')
except IOError:
print('ERROR!')
sys.exit('No such file: sample.xls')
import xlwt
import xlrd
import xlutils.copy
try:
#將範本打開
inbook = xlrd.open_workbook('sample.xls', formatting_info=True)
#複製給outbook物件
outbook = xlutils.copy.copy(inbook)
#取得分頁並將字串寫入座標為(5,5)的欄位
#預設是不能複寫欄位裡的資料喔!
outbook.get_sheet(0).write(5,5,"ILoveBaseball")
#若儲存為同樣的檔名會出現Permission denied的錯誤訊息喔!
outbook.save('mynote.xls')
except IOError:
print('ERROR!')
sys.exit('No such file: sample.xls')
註:
如果終端輸出的資料『長的很整齊』的話,就不需要搞的這麼複雜,因為CSV格式的檔案支援以逗號或空白分隔的資料,當選用Excel開啟副檔名為CSV的檔案,做些簡單的設定即可讓資料完美呈現喔,來看看下面的範例吧!
$ git log --oneline --pretty="%h,%s,%an" > example.csv
接著選用Excel開啟example.csv,並且選擇以逗號分隔,結果呈現如圖所示。
GitHub:
https://github.com/Kuanlin-Chen/ChangeNote
留言
張貼留言