用python讀取json文件,並放入Excel

最近需要讀很多json文件,讀到的數據放入excel裏。
梳理了一下流程:
1. 導入os,glob模塊,讀取不同文件夾的不同json文件,放入excel不同的位置
2. 導入json模塊,讀取json文件,查看json文件格式,是否有亂碼,手動處理或者代碼中處理
3. 導入xlwt模塊,寫Excel,將可以固定的內容寫入excel,作爲模版

主要難點:
1. 如何讀取多個人的數據(json文件)。
2. 如何判斷每個人的文件夾裏的Question都有哪些,有的讀出來放到excel相應位置,沒有的怎麼辦,是用一個符號代替,填進去,還是空着。
3. 如何把每個人的數據橫向的放入excel正確的位置。
4. 如何將多個人的數據放入excel正確的位置。

我個人首先解決的是寫一個excel,將固定內容寫進去,製作一個模版。

# 創建一個工作簿
f = xlwt.Workbook()
# 創建一個sheet
sheet1 = f.add_sheet('P1D1',cell_overwrite_ok=True)
# 寫內容,row行數,column列數(都是從0開始)
sheet1.write(row,column,'P1D1')
'''
合併單元格sheet.write_merge(x,x+m,y,w+n,string,style)
x表示行,y表示列,m表示跨行個數,n表示跨列個數
string表示寫入的單元格內容,style表示單元格風格
'''
'''
第一個參數2表示第3行,第二個參數2表示還是第三行,跨行個數相當於0
第三個參數1表示第2列,第四個參數4表示第5列,合併的單元格相當於是第3行的第2列到第5列
'''
sheet1.write_merge(2, 2, 1, 4, 'Touch-01', set_style())
'''
如果一行有很多的固定內容,可以不指定位置,通過遍歷依次放入
'''
# 生成第4行,將row13的參數依次寫進去
row13 = ['數據', 'DrawStart', 'DrawStop', 'TimeBegin', 'TimeEnd']
for a0 in range(0, len(row13)):
    sheet1.write(3, a0, row13[a0], set_style())
'''
這就是一個sheet的寫法,如果一個Excel表格有很多sheet,依次add_sheet,寫內容
'''

其次,解決的問題是讀取json文件,代碼很簡單。
需要注意的是,如果json文件中內容含有中文,代碼中需加入encoding=’utf-8’,不會報錯,正確讀出中文。
Question_02.json文件打開就說file was loaded in the wrong encoding:’utf-8’,中文顯示的地方全是亂碼,爲了讓代碼正常運行,需加入errors=’ignore’

with open('xxx','r',encoding='utf-8') as f:
    json.load(f)

最重要的就是流程1的解決,主要難點也集中在這裏,主要自己對於循環和遍歷的實際應用不到位。

'''
path可以設絕對路徑,也可以設相對路徑
絕對路徑:就是最完整的路徑,'\'在python中爲字符串轉義字符,所以用r'\'表示絕對路徑
相對路徑:不完整的路徑,就是當前py文件所處的路徑
你寫的相對路徑必須是當前文件夾A裏的文件a或者A裏的文件夾B裏的文件纔可以open
'/'表示相對路徑,等同於'\\'
path1=os.path.abspath('.')#獲取當前腳本所在的路徑  
path2=os.path.abspath('..')#獲取當前腳本所在路徑的上一級路徑  
'''
path='xxx'
def traversal1(sheet,row):
    # 判斷給出的路徑是否真的存在
    if os.path.exists(path):
        '''glob.glob 獲取指定目錄下的所有文件(夾)
           返回所有匹配的文件路徑列表
           可以用絕對路徑,也可以用相對路徑
        '''
        files = glob.glob(path + '\\*')
        # print(files)
        # files返回的是一個list,遍歷這個list
        for file in files:
            Q1 = file + '\\' +'Question_01.json'
            # 判斷給出的路徑是否真的存在
            if os.path.exists(Q1):
                '''
                打開json文件
                內容有中文要加encoding='utf-8'
                內容有亂碼要加errors='ignore'
                json.load 讀json文件
                '''
                with open(Q1,'r',encoding='utf-8') as f:
                    Q1= json.load(f)
                    '''
                    由於每個json文件都是一個dict,都有datanum這個key,對應的value就是次數
                    通過Q1['DataNum]讀出次數,設一個初始的空list,遍歷次數,將'Touch-01' 分解成 'Touch-0' + str(i+1)
                    再設一個臨時的空list,用list.append 依次讀出不同的touch裏的不同的key的value並將其放入
                    用list.extend 將臨時的list放入初始的list
                    excel表格裏的touch是10次,根據json文件讀取出的實際次數,不夠10次的位置用 '-'代替
                    所以有了XL公式,(10-datanum)* 4,將XL放入初始list
                    '''
                    datanum = Q1['DataNum']
                    data_infos_list = []
                    for i in range(datanum):
                        touch_key = 'Touch-0' + str(i + 1)
                        temp = []
                        temp.append(Q1[touch_key][0]['DrawStart'])
                        temp.append(Q1[touch_key][0]['DrawStop'])
                        temp.append(Q1[touch_key][0]['TimeBegin'])
                        temp.append(Q1[touch_key][0]['TimeEnd'])
                        data_infos_list.extend(temp)
                    XL = ['-'] * (10 - datanum) * 4
                    data_infos_list.extend(XL)
            # 如果該路徑不存在
            else:
                # 設一個空list,將'-'填充入excel-Question_01的所有位置
                data_infos_list = []
                XL = ['-'] * 40
                data_infos_list.extend(XL)
            '''
            在最後設置一個循環,data_infos_list裏已經有了相應的元素,遍歷之,sheet,write 寫入相應位置,row是行,j是列
            j=j+1在循環內,row=row+1在循環外
            row和sheet是函數的兩個參數,調用該函數的時候,設置行數和指定sheet
            '''
            j = 1
            for data_infos in data_infos_list:
                sheet.write(row, j, data_infos)
                j += 1
            row += 1
'''
之前str分割規則只適用於datanum在0到9之間
在讀取Question_02.json的時候要注意datanum可能爲10
'''
'''
                    這裏和之前有所區別,因爲datanum可能大於9,'Touch-0' +str(i+1)這種情況只能i在0到8之間
                    'Touch-010'是讀不出來的,因爲json文件裏是'Touch-10'
                    所以這裏做一個判斷,如果datanum小於10,str分解成'Touch-0' + str(i+1)
                    如果datanum大於等於10,
                    i小於9的部分,str分解成'Touch-0' + str(i+1)
                    i大於等於9的部分,str分解成'Touch-' +str(i+1)

'''
                    if datanum < 10:
                        for i in range(datanum):
                            touch_key = 'Touch-0' + str(i + 1)
                            temp = []
                            # 在讀TotalTime這個key的時候,要注意之前還包含了一個參數Book
                            temp.append(Q2[touch_key][0]['Book'][0]['TotalTime'])
                            temp.append(Q2[touch_key][0]['Queue'])
                            temp.append(Q2[touch_key][0]['Success'])
                            temp.append(Q2[touch_key][0]['TimeBegin'])
                            temp.append(Q2[touch_key][0]['TimeEnd'])
                            data_infos_list.extend(temp)
                        XL = ['-'] * (10 - datanum) * 5
                        data_infos_list.extend(XL)
                    else:
                        for i in range(datanum):
                            if i < 9:
                                touch_key = 'Touch-0' + str(i + 1)
                            elif i >= 9:
                                touch_key = 'Touch-' + str(i + 1)
                            temp = []
                            temp.append(Q2[touch_key][0]['Book'][0]['TotalTime'])
                            temp.append(Q2[touch_key][0]['Queue'])
                            temp.append(Q2[touch_key][0]['Success'])
                            temp.append(Q2[touch_key][0]['TimeBegin'])
                            temp.append(Q2[touch_key][0]['TimeEnd'])
                            data_infos_list.extend(temp)
                        XL = ['-'] * (10 - datanum) * 5
                        data_infos_list.extend(XL)
            else:
                data_infos_list = []
                XL = ['-'] * 50
                data_infos_list.extend(XL)
'''
這個解決了如何讀取一個人的數據放入Excel之後,自動加一行,放入下一個人的數據
讀取的json文件本身是dict,data_list必須爲列表形式才能遍歷
'''
i = 1
for data in data_list:
    sheet.write(row,i,data)
    i += 1
row += 1

PS:
os模塊裏,最好先做判斷 if os.path.exists(path):
glob.glob獲取指定目錄下的所有文件(夾),返回所有匹配的文件路徑列表

以上就是持續了10天的task的心得,對於循環,遍歷,判斷有了更深的理解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章