Python實戰之Excel資料按索引更新
阿新 • • 發佈:2018-11-14
在日常工作中,我們經常需要需要批量更新資料,比如有個destination表,裡面有一列的資料需要被更新,更新的依據為reference表,python指令碼執行前和執行後的資料列示意圖如下:
我們使用Excel檔案作為config引數表,reference和destination也使用Excel作為資料,其中config引數如下圖,python例子讀取該檔案中的引數,獲取各個引數的值,從而獲取源資料和目的資料資訊。
實現程式碼設計為幾個函式,其各個功能如下:
函式名 | 函式功能 |
---|---|
get_str_for_cell(cell_value) |
把傳入的內容轉換為字串格式,主要針對浮點型資料。 在python讀取Excel單元格時,會把數值讀為浮點數,此處方法重新轉換為整數型的字串 |
get_saveas_name(origin_name) |
把傳入的檔名改名為帶時間戳,例如原檔名為abc.xls,則返回abc_2018-11-13-10-10-07.xls。 |
get_mainpara() |
獲config檔案中main的sheet頁的引數,該資訊是源資料和目標資料的定位資訊。 |
get_optionpara() |
獲config檔案中option的sheet頁的引數,該資訊是資料替換的引數,比如是否進行force替換。 |
get_reference_dict(main_paras) |
根據main引數獲取到reference資料的資料字典。 |
update_xlsx_file(main_paras, option_paras, reference_dict) |
更新destination的表格資訊 |
整個功能實現程式碼如下:
import xlrd
import xlutils.copy
import time
import datetime
def get_str_for_cell(cell_value):
if isinstance(cell_value, float):
if cell_value == int(cell_value):
cell_value = int(cell_value)
return str(cell_value)
def get_saveas_name(origin_name):
now_time = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
if origin_name.rfind('.'):
return origin_name.split('.')[0] + "_" + str(now_time) + "." + origin_name.split('.')[1]
def get_mainpara():
main_paras = {}
wb = xlrd.open_workbook("config.xlsx")
ws = wb.sheet_by_name(u"main")
rown = 1; coln = 1
main_paras["ReferenceFileName"] = ws.cell_value(rown,coln)
rown = 2
main_paras["ReferenceSheetName"] = ws.cell_value(rown,coln)
rown = 3
main_paras["ReferenceColumnName"] = ws.cell_value(rown,coln)
rown = 4
main_paras["ReferenceDataColumnName"] = ws.cell_value(rown,coln)
rown = 5
main_paras["DestinationFileName"] = ws.cell_value(rown,coln)
rown = 6
main_paras["DestinationSheetName"] = ws.cell_value(rown,coln)
rown = 7
main_paras["DestinationColumnName"] = ws.cell_value(rown,coln)
rown = 8
main_paras["DestinationDataColumnName"] = ws.cell_value(rown,coln)
wb = xlrd.open_workbook(main_paras["ReferenceFileName"])
ws = wb.sheet_by_name(main_paras["ReferenceSheetName"])
reference_column_index = get_column_index(ws, main_paras["ReferenceColumnName"])
reference_data_column_index = get_column_index(ws, main_paras["ReferenceDataColumnName"])
main_paras["reference_column_index"] = reference_column_index
main_paras["reference_data_column_index"] = reference_data_column_index
wb = xlrd.open_workbook(main_paras["DestinationFileName"])
ws = wb.sheet_by_name(main_paras["DestinationSheetName"])
dest_column_index = get_column_index(ws, main_paras["DestinationColumnName"])
dest_data_column_index = get_column_index(ws, main_paras["DestinationDataColumnName"])
main_paras["dest_column_index"] = dest_column_index
main_paras["dest_data_column_index"] = dest_data_column_index
return main_paras
def get_optionpara():
option_paras = {}
wb = xlrd.open_workbook("config.xlsx")
ws = wb.sheet_by_name(u"option")
rown = 1; coln = 1
option_paras["ForceReplace"] = ws.cell_value(rown,coln)
return option_paras
def get_column_index(table, column_name):
column_index = -1
for i in range(table.ncols):
if(table.cell_value(0, i) == column_name):
column_index = i
break
return column_index
def get_reference_dict(main_paras):
reference_dict = {}
wb = xlrd.open_workbook(main_paras["ReferenceFileName"])
ws = wb.sheet_by_name(main_paras["ReferenceSheetName"])
reference_column_index = main_paras["reference_column_index"]
reference_data_column_index = main_paras["reference_data_column_index"]
num_rows = ws.nrows
for rown in range(num_rows):
if rown == 0:
continue
reference_dict[get_str_for_cell(ws.cell_value(rown, reference_column_index))] = get_str_for_cell(ws.cell_value(rown, reference_data_column_index))
return reference_dict
def update_xlsx_file(main_paras, option_paras, reference_dict):
rb = xlrd.open_workbook(main_paras["DestinationFileName"], formatting_info = True)
wb = xlutils.copy.copy(rb)
ws_origin = rb.sheet_by_name(main_paras["DestinationSheetName"])
ws = wb.get_sheet(main_paras["DestinationSheetName"])
dest_column_index = main_paras["dest_column_index"]
dest_data_column_index = main_paras["dest_data_column_index"]
writen_count = 0
num_rows = ws_origin.nrows
for rown in range(num_rows):
if rown < 5:
continue
key_cell = get_str_for_cell(ws_origin.cell_value(rown, dest_column_index))
if key_cell not in reference_dict:
print("error! can't find the value for key:", key_cell)
continue
data_value = reference_dict.get(key_cell)
data_value_old = ws_origin.cell_value(rown, dest_data_column_index)
if data_value == data_value_old:
continue
ws.write(rown, dest_data_column_index, data_value)
ws.write(rown, 1, "M")
writen_count = writen_count + 1
print("totally modified rows:", writen_count)
wb.save(get_saveas_name(main_paras["DestinationFileName"]))
return
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())), "PlanDataReplacer started work, please wait...")
main_paras = get_mainpara()
print("main_paras:", main_paras)
option_paras = get_optionpara()
print("option_paras:", option_paras)
reference_dict = get_reference_dict(main_paras)
print("reference_dict length:", len(reference_dict))
#print(reference_dict)
update_xlsx_file(main_paras, option_paras, reference_dict)
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())), "PlanDataReplacer work complete.")
執行後列印資訊如下,則說明有479行資料已被更新。
如果您喜歡這篇文章,別忘了點贊和評論哦!