0x00問(wèn)題背景
前段時(shí)間在工作中遇到了一個(gè)需求藕溅,簡(jiǎn)單介紹就是需要在過(guò)去6個(gè)月中某市每天不同蔬菜的菜價(jià)中查找公司所采購(gòu)特定蔬菜對(duì)應(yīng)那天的價(jià)格,計(jì)算差值偶妖,看似簡(jiǎn)單但數(shù)據(jù)量龐大,光錄入就花了不少時(shí)間愤诱,耗費(fèi)了大家不少精力科吭,當(dāng)時(shí)想到用python解決這個(gè)問(wèn)題,但是時(shí)間緊迫沒(méi)有認(rèn)真研究這幾個(gè)交互Excle的庫(kù)牺弄,依照當(dāng)時(shí)搜索的部分資料和自己親身的使用來(lái)看姻几,主要有:
xlwt
xlrd
xlutils
xlwings
openpyxl
這幾個(gè)庫(kù)各有好處,也各有缺陷,綜合來(lái)看,上次直接使用了openpyxl是一個(gè)比較正確的選擇豁陆。
0x01python交互庫(kù)介紹
關(guān)于這幾個(gè)庫(kù)的介紹網(wǎng)上很多了盒音,安裝也都非常簡(jiǎn)單厘熟,可以按照pip install XXX
的方式來(lái)安裝,我將在這次問(wèn)題中遇到的幾個(gè)重要方面做記錄:
xlrd&&xlwt&&xlutils
- 首先搜到的就是兩個(gè)最簡(jiǎn)單的庫(kù)xlwt和xlrd购撼,兩個(gè)庫(kù)功能分開(kāi)跪削,一個(gè)負(fù)責(zé)讀另一個(gè)負(fù)責(zé)寫(xiě),但美中不足的就是只能支持對(duì)xls的寫(xiě)揩局,所以不滿足我們的使用需求廓旬,
import xlrd
import xlwt
from xlutils.copy import copy
book = xlrd.open_workbook() #打開(kāi)一個(gè)表格文件,句柄傳給book
count = book.sheets()#獲取sheets對(duì)象谐腰,這時(shí)使用len()獲得sheet對(duì)象個(gè)數(shù)
count = book.nsheets #共有多少個(gè)sheet
獲取一個(gè)sheet有兩種方式,通過(guò)名字或通過(guò)編號(hào)涩盾,對(duì)應(yīng)方法為book.sheet_by_index(0)
或book.sheet_by_name
十气,獲得sheet對(duì)象后讀取特定單元格值cell_value(0,10)
,括號(hào)內(nèi)為行列值春霍,均從0開(kāi)始計(jì)砸西。且同類型的單元格數(shù)值可以直接比較。
sheet1.nrows #獲取行數(shù),用來(lái)遍歷
xlwt創(chuàng)建一個(gè)新的工作表并對(duì)其進(jìn)行修改芹枷,雖然修改的功能強(qiáng)大衅疙,但不能對(duì)xlsx修改,也不能在已有的表中做修改鸳慈,所以還是有很多的限制的饱溢。而使用了xlutils導(dǎo)入的copy方法復(fù)制一個(gè)新的表格再利用xlwt對(duì)其修改時(shí),操作后發(fā)現(xiàn)生成的xlsx不可讀了走芋,文件損壞绩郎,也饒了不少?gòu)澛贰?/p>
xlwings
- 大家都說(shuō)xlwings是最強(qiáng)大的excle交互庫(kù),包含了讀寫(xiě)的全部功能翁逞,使用也比較簡(jiǎn)單肋杖,但是比起其他的庫(kù)來(lái)說(shuō),操作的方式好像有呢么一丟丟不同挖函,同樣我們也了解一下打開(kāi)文件状植、獲取sheet、獲取行數(shù)怨喘、獲取單元格值這幾個(gè)基本操作津畸。
導(dǎo)入庫(kù)運(yùn)行后發(fā)現(xiàn)還需要依賴庫(kù)win32api
1.可以使用pip install pypiwin32
解決問(wèn)題
2.在https://sourceforge.net/projects/pywin32中下載對(duì)應(yīng)自己python版本的win32包。安裝前關(guān)閉占用python的進(jìn)程哲思,一路next洼畅。
import xlwings
book = xlwings.Book(strName) #
sheet1 = book.sheets[0] #選擇一個(gè)sheet對(duì)象,編號(hào)為0
sheet2 = book.sheet('9.17') #選擇一個(gè)sheet對(duì)象棚赔,名稱為9.17
print sheet1[0,0].value #讀取0帝簇,0單元格的內(nèi)容以index形式索引
print sheet1.range('a1').value #以單元格名稱為索引讀取
讀取簡(jiǎn)單,對(duì)應(yīng)的寫(xiě)入也非常簡(jiǎn)單
sheet1[0,0].value = "XXX"
sheet1.range('a1').value = "XXX"
獲取行列數(shù)靠益,用來(lái)遍歷
nrow = sheet1.api.UsedRange.Rows.count
ncol = sheet1.api.UsedRange.Columns.count
基本也只用到這些操作了丧肴,下面著重講講我所用的openpyxl。
openpyxl
這個(gè)庫(kù)是在實(shí)踐中所用的庫(kù)胧后,使用簡(jiǎn)單芋浮,功能強(qiáng)大,與xlwings很難比較孰強(qiáng)孰弱壳快,都能滿足我們的時(shí)間需求纸巷。
import openpyxl
work = openpyxl.load_workbook('Test.xlsx') #打開(kāi)一個(gè)工作簿
sheet_names = work.get_sheet_names() #獲得sheet_name的數(shù)組
sheet1 = work.get_sheet_by_name('9.99') #以sheet名稱獲取sheet對(duì)象
sheet2 = work.get_sheet_by_name(sheet_names[0]) #獲取名稱數(shù)組后按索引,可以在不知道名稱的情況下遍歷
print sheet1.cell(1,1).value #需要注意的是單元格從1眶痰,1開(kāi)始瘤旨,而不是0
sheet1.cell(1,1).value = '111' #寫(xiě)單元格
print sheet1.max_row #總行數(shù)
print sheet1.max_column #總列數(shù)
work.save('001T_ok.xlsx')#保存更名
0x02問(wèn)題分析
接觸這個(gè)任務(wù)時(shí)有這個(gè)想法是第一次將python運(yùn)用到實(shí)際,想要解放生產(chǎn)力竖伯,所以還是遇到了很多的小問(wèn)題存哲,記錄一下以備不時(shí)之需因宇,整個(gè)實(shí)踐可以細(xì)化為幾個(gè)部分,這也是在遇到問(wèn)題后的分析思路祟偷。
第一察滑,操作方面:對(duì)需要修改表格的操作,包括打開(kāi)修肠,遍歷贺辰,讀寫(xiě),然后保存氛赐。
第二魂爪,邏輯方面:首先從第一項(xiàng)菜品開(kāi)始,在本市對(duì)應(yīng)日期的所有菜品中查找艰管,找到對(duì)應(yīng)價(jià)格滓侍,填寫(xiě)上去;>其次是有名稱不統(tǒng)一的情況出現(xiàn)牲芋,例如“大蔥”撩笆,“蔥”、“姜”缸浦,“生姜”等同類菜品的不同叫法夕冲。
第三,編碼方面:名稱均為漢字 裂逐,分為打印輸出的編碼問(wèn)題和日期比較的編碼問(wèn)題歹鱼。
第四,庫(kù)對(duì)文件格式的支持問(wèn)題:選擇xlwings和openpyxl這兩個(gè)庫(kù)來(lái)完成實(shí)踐卜高。
0x03代碼實(shí)現(xiàn)
細(xì)化為四個(gè)問(wèn)題后開(kāi)始代碼的實(shí)現(xiàn)弥姻,操作方面上文已經(jīng)提到。
1.名稱不一致問(wèn)題又建了一個(gè)名稱的更新表 Csql.xlsx庭敦,可以讓查找不到的菜品在新的xlsx中替換名字查詢,還可以隨時(shí)追加新的內(nèi)容薪缆,這時(shí)就再次遍歷表就可以了秧廉。
2.日期問(wèn)題在每個(gè)錄入的表中做標(biāo)記,使用excle中內(nèi)容來(lái)互相比較拣帽,避免格式問(wèn)題疼电。
3.查詢不到的使用try跳過(guò)。
4.使用flag位標(biāo)記减拭。
實(shí)現(xiàn)的代碼也很簡(jiǎn)單澜沟,主要是記錄一下使用的庫(kù)和基本的操作。