用Python 進行Excel 文件的整理大致分爲這幾個流程: 讀取-整理-寫入
有時寫入的時候需要按照規定的格式填入指定的位置,這時可以選擇整理的時候就按照指定的位置進行整理,方便寫入。
首先是模塊選擇,這裏我選擇了openpyxl , Pandas 模塊。Openpyxl用於操作Excel寫入可以說是相當方便,而Pandas用於整理數據
也是不錯的選擇。
對於數據源並不是很規範的時候,整理的過程耗時比較長。
下面開始我們的示例,這是我們單位工作時用到的表,表數據其實是非常不規範的。
以下兩張表可以視爲兩個報告表,並不是很好的數據源。所以整理數據源就是第一大塊工作了。
這是src表,包括了pn列和日期列
這是tg表,有pn列 model列,部分日期列
========================這是分割線================================
1. 文件讀取 :
Openpyxl : wb = load_workbook(‘url’) 除了url以外還有幾個參數可供選擇 : read_only[大文件時啓用] ; data_only[公式or 值]
Wb.sheetnames – 獲取sheet名
Wb[‘sheetname’] – 獲取 sheet
sheet[‘A1’].value || sheet.cell(row=1,column=1).value – 獲取指定單元格值
sheet.max_row , sheet.max_column - 獲取行列數
sheet[‘A1’: ‘C3’] – 獲取指定區域
Pandas : src = pd.read_excel(‘url’,sheet_name=’’,header=0) 以外還有幾個參數: sheet_name[可以寫序號,可以選多張] ; index_col[設置爲索引列] (此方法讀取出的數據爲DataFrame格式)
Src[‘column’] – 讀取指定列數據
import pandas as pd
from openpyxl import load_workbook
# 讀取文件
src = pd.DataFrame(pd.read_excel('/Users/Documents/Code/Python/excel/dataSource.xlsx',sheet_name=0,header=2))
tg = pd.DataFrame(pd.read_excel('/Users/Documents/Code/Python/excel/report.xlsx',sheet_name=0,header=3))
tg_wb = load_workbook('/Users/Documents/Code/Python/excel/report.xlsx',data_only=True)
src_wb = load_workbook('/Users/Documents/Code/Python/excel/dataSource.xlsx',data_only=True)
tg_sheet = tg_wb['Sheet1']
src_sheet = src_wb['Sheet1']
=========================這是分割線==========================
2. 數據整理
定義索引:使用Pandas讀取的數據可以定義序列 src.set_index(‘index’)
# 設置索引
df_src = src.set_index('pn')
對於序列不規範情況,找出其規律比如分組
# src_pn集合
src_pnList = []
for pn in src['pn']:
src_pnList.append(pn)
篩選: 確定一個基準列後,就可以進行篩選。篩選一般用loc , iloc 比較多 loc[1,’column’] , 對於序列化的DataFrame 可直接用loc[‘row’,’column’] ; iloc一般爲iloc[1,1]
遍歷:整理時一般使用 tg = update(src) 比較方便,但前提是序列一致。不一致時我們需要自己重寫。
特殊情況處理:待寫入數據爲nan時,無法寫入新數據,需要先判斷用pd.isna(),然後可以賦值爲0
for i in range(0,tg.shape[0]):
# 如果model 是 1
if tg.loc[i,'model'] == 1:
# 如果有一個元素
if len(tg.loc[i,'pn']) == 1:
for j in range(3,tg.shape[1]+1):
# 寫入
tg.loc[i,tg.columns[j-1]] = df_src.loc[tg.loc[i,'pn'],tg.columns[j-1]]
# 如果有多個元素
else:
# 拆分成數組
pn_list = (tg.loc[i,'pn']).split('/')
# 遍歷元素組
for n in pn_list:
# 如果在數據源內存在
if n in src_pnList:
# 遍歷目標
for k in range(3,tg.shape[1]+1):
# 如果目標單元格是空
if pd.isna(tg.loc[i,tg.columns[k-1]]):
tg.loc[i,tg.columns[k-1]] = 0
# 累積數字
tg.loc[i,tg.columns[k-1]] += df_src.loc[n,tg.columns[k-1]]
至此 數據的整理就差不多了
別忘記給整理的數據添加一個索引,並且確定唯一值
# 添加整理好的索引 - 確認待寫入的唯一值
df_tg = tg[tg['model'] == 1].set_index('pn')
=====================我是分割線==========================
直接寫入:由於數據整理時依照待寫入數據的格式整理,故寫入過程比較簡單。可直接使用cell(row=1,column=1).value進行
最後別忘記wb.save(‘url’)
# df_tg pn 集合
df_tg_pnList = []
for df_tg_pn in df_tg.index:
df_tg_pnList.append(df_tg_pn)
# 遍歷循環寫入
for i in range(5, tg_sheet.max_row + 1):
# 獲取目標源的pn
tg_pn = tg_sheet.cell(row=i,column=1).value
# 如果目標源pn在DataFrame內,並且model==1
if (tg_pn in df_tg_pnList) & (tg_sheet.cell(row=i,column=2).value == 1):
# 遍歷日期相關所有列
for j in range(3, tg_sheet.max_column + 1):
# 賦值
tg_sheet.cell(row=i,column=j).value = df_tg.loc[tg_pn,df_tg.columns[j-2]]
# 寫入excel
tg_wb.save('/Users/zean/Documents/Code/Python/excel/reportNew.xlsx')
=========================大功告成==========================