本章介紹excel自動(dòng)化辦公——openpyxl庫的使用,。我覺得openpyxl是一款輕量級(jí)的excel操作庫,,適合用于一些基本的操作構(gòu)建,,如果涉及批量處理數(shù)據(jù),如求一整列的最大值最小值等,,無疑是pandas更好,;對(duì)于一些單元格背景填充、單元格合并,、批量創(chuàng)建sheet等的操作,,無疑是openpyxl好,,因?yàn)閜andas無法方便地完成此類操作,。python庫之間的兼容性大,,pandas導(dǎo)出到excel時(shí),,如果沒有安裝openpyxl,將無法完成該操作,??梢哉f,學(xué)好openpyxl庫,,能為以后學(xué)pandas數(shù)據(jù)分析打好良好的基礎(chǔ),。 必讀:openpyxl 舊庫新庫變化似乎有點(diǎn)大,如果和我的不一樣,,特別是 iter_rows函數(shù),,那么很大可能是因?yàn)槟愕膐penpyxl庫不是最新的。導(dǎo)入庫后可運(yùn)行代碼 print(openpyxl.__version__) 查看其版本,。也可以通過 win +R 輸入cmd,,確認(rèn),打開cmd黑窗后輸入pip install --upgrade openpyxl 去更新庫,。 目錄 1,、新建工作簿workbook及保存
運(yùn)行后,在目錄下參數(shù)一個(gè)名叫 “新建工作簿” 的excel文件,,因?yàn)闆]有任何內(nèi)容寫入,,所以里面是空的,打開文件,,內(nèi)容如下: 2,、創(chuàng)建/新增工作表sheet
在這先說明一下工作簿和工作表的區(qū)別,,因?yàn)槲覄倢W(xué)也是不知道。工作簿是指這個(gè)excel文件,,而工作表是指這個(gè)excel里的表,。
.create_sheet 函數(shù)中,,當(dāng) title不寫時(shí),創(chuàng)建工作表的名字為sheet1,,再建即為sheet2,,依此類推。當(dāng) index不寫時(shí),,默認(rèn)放在最后面,;當(dāng) index為0,即放在最前面,,1即放在第二位,,依此類推。如下為index=0的情況: 當(dāng)我們需要批量創(chuàng)建2023年1月每天的工作表時(shí),,可以使用for循環(huán)批量生成:
3、移除工作表wb.remove(worksheet) 移除工作表,,其中worksheet為工作表對(duì)象,,而非工作表名稱。
注意,在創(chuàng)建工作簿的時(shí)候就已經(jīng)自動(dòng)創(chuàng)建了一個(gè)名叫 “Sheet” 的工作表,,首字母是大寫的,。移除工作表時(shí),要先找到工作表對(duì)象 wb['Sheet'],,再把它放進(jìn)remove函數(shù)中進(jìn)行移除,。 此次創(chuàng)建的工作簿就沒有上圖的 “Sheet” 表了。 4,、讀取現(xiàn)有excel工作簿openpyxl.load_workbook(filename, read_only=False, keep_vba=False, data_only=False, guess_types=False, keep_links=True) 讀取excel文件,。
我們可以手動(dòng)創(chuàng)建一個(gè)文件然后用代碼去讀取,,或者直接讀取我們上面創(chuàng)建的文件,。以下直接讀取我們上面創(chuàng)建的 "批量創(chuàng)建1月每天的表.xlsx" 文件去演示 讀取工作簿和工作表:
第一行代碼為讀取文件,其他參數(shù)一般默認(rèn)就好,。第二行是獲取指定工作表,,返回一個(gè)對(duì)象。第三行輸出該工作表的名稱,。openpyxl總體的操作就是,,先讀取文件,后選擇相應(yīng)的sheet表,,然后在表的基礎(chǔ)上進(jìn)行各種操作,。 5、獲取所有工作表及名稱① wb.worksheets 獲取所有工作表,,返回一個(gè)工作表對(duì)象,。可以用 .title去提取其名稱,。
all_sheet 輸出了所有的工作表,。但該輸出為一個(gè)對(duì)象,想要選擇表格需要先提取其名稱,,才能放入wb[]中,,否則會(huì)報(bào)錯(cuò)。
② wb.sheetnames 獲取所有工作表,,返回一個(gè)工作表名稱,。
該函數(shù)直接返回了所有工作表的名稱。 6,、獲取活躍工作表wb.active 獲取活躍工作表,。活躍工作表即在關(guān)閉工作簿的那一刻,,當(dāng)前處于哪個(gè)工作表,,那活躍工作表就是這個(gè)。
如果重新打開改工作簿,,把鼠標(biāo)選擇在最后一個(gè)工作表,,隨便點(diǎn)幾個(gè)單元格,然后保存,。那么活躍工作表就是最后一個(gè)工作表了,。它表示的是文件在關(guān)閉前的最后更改的那個(gè)工作表。 7,、更改工作表名稱sheet.title = ? 先獲取到該工作表的名稱,,再=?,,以重命名該工作表,。
改后,,該工作表的名稱為: 除了直接改名稱,,也可以在原來的名稱上增加字符,如:
重命名還有更多的操作,,待小伙伴自己去研究。 8,、復(fù)制工作表wb.copy_worksheet(worksheet) 復(fù)制工作表,。其中worksheet為工作表對(duì)象,而非工作表名稱,,工作表對(duì)象可用 工作簿[工作表名稱] 即 wb['工作表名稱'] 獲取,。
復(fù)制文件到最后(似乎只能復(fù)制到最后,,沒有index可以選擇),。 9、獲取單元格的值獲取單元格的有兩種方法:① sheet['單元格'].value ② sheet.cell(row,column).value ① sheet['單元格'].value 獲取該單元格的值,。
② sheet.cell(row, column, value=None) 獲取第row行,,第column列的單元格。
讀取第4行第2列單元格的值為2300??芍?,該函數(shù)的參數(shù)row和column都是從1開始計(jì)算的。需要記得,,先行后列,,不記得的話也可以以傳參的形式輸入,如:sheet.cell(row=4,column=2).value,。 10,、寫入/更改單元格的值① 當(dāng)sheet.cell(row, column, value=None)函數(shù)傳入value參數(shù)時(shí),,該單元格的值會(huì)被改成value的值,從而更改單元格的值,。如:
② 直接通過對(duì) sheet.cell(row, column).value 進(jìn)行賦值。
兩種方法都可以更改單元格的值,,本人用方法二比較多,,具體要看個(gè)人習(xí)慣。如果需要獲取多個(gè)單元格的值,,可以用 for循環(huán)對(duì) row和 column參數(shù)進(jìn)行賦值獲得,。 如果需要批量寫入/修改數(shù)據(jù)(一小塊區(qū)域),openpyxl在這方面并不占優(yōu)勢(shì),,需要把每個(gè)單元格逐一遍歷出來,,再進(jìn)行寫入/修改,學(xué)了下面的遍歷/獲取一小塊區(qū)域內(nèi)容,,你就會(huì)有靈感如何逐一遍歷出來再寫入/修改數(shù)據(jù)了,。 11、寫入整行數(shù)據(jù)再工作中不可能一個(gè)一個(gè)數(shù)據(jù)地寫入,,也為了防止出錯(cuò),,通常以一整行的方式寫入。以一整行形式寫入需要為一個(gè)列表,,直接在sheet里append一個(gè)列表即可,。
需要寫入多行就用 for循環(huán),一次一次地把每行寫入,。 12,、獲取一小塊區(qū)域的內(nèi)容獲取小塊區(qū)域單元格的值由兩種方法:① 直接通過[]對(duì)一小塊區(qū)域進(jìn)行提取。② 通過函數(shù)sheet.iter_rows() 或 sheet.iter_cols() 獲得,。 ① 通過[]獲得 在講解之前,,我們先看看對(duì)于一小塊區(qū)域,openpyxl是如何逐一提取單元格的值的,。
可見,,對(duì)于一小塊區(qū)域 sg,openpyxl的[]提取法是先將行遍歷出來,,再將該行的單元格一個(gè)一個(gè)按順序的提取的,。如此,我們可以先遍歷每行,,再遍歷該行的每個(gè)單元格去獲得值:
② sheet.iter_rows(min_row=None, max_row=None, min_col=None, max_col=None, values_only=False)
這次我們就不把一個(gè)輸出為一行了,,我們把(表格的)一行輸出為(屏幕的)一行,。 輸出結(jié)果為一個(gè)對(duì)象,,此時(shí)如果需要得到值,可直接用列表生成式 或者 一個(gè)個(gè)再次遍歷出來,,取 .title即可,。而當(dāng)我們?cè)O(shè)置 values_only為True時(shí),輸出結(jié)果為值,。
③ sheet.iter_cols(min_col=None, max_col=None, min_row=None, max_row=None, values_only=False)
該函數(shù)的參數(shù)和上一個(gè)沒有區(qū)別,意思也是一樣,,但是就是參數(shù)的位置不同,。sheet.iter_rows各參數(shù)的順序是最小行、最大行,、最小列,、最大列;而 sheet.iter_cols各參數(shù)的順序是最小列,、最大列,、最小行、最大行,。一句話,,就是iter_rows先行后列,iter_cols先列后行,。這個(gè)對(duì)于位置傳參是非常重要的,,而對(duì)于關(guān)鍵字傳參沒有影響,需要注意,。
我們說過,,sheet.iter_cols為先列后行,所以是提取2-6列 3-5行的內(nèi)容。 如果你的和我的不一樣,,那么很有可能你的openpyxl庫不是最新的,。 13、獲取最小行,、最大行,、最小列、最大列
獲取到最小最大行列后可以更方便地對(duì)區(qū)域進(jìn)行迭代,。如第十一的獲取一小塊內(nèi)容,在不知道最大行列的時(shí)候,,需要取到最大行的情況,,就需要用到了。下面舉一個(gè)例子,,獲取第3行以后的行 第5列以后的列組成的區(qū)域:
14,、獲取一整個(gè)sheet的內(nèi)容sheet.values 獲取sheet表中所有值,返回的是一個(gè)可迭代對(duì)象,。如果需要得到值,,可對(duì)該可迭代對(duì)象進(jìn)行列表化處理 list(sheet.values)。
返回的數(shù)據(jù)依舊是以行存儲(chǔ)的,,即每一行作為一個(gè)整體元素存于列表中,。這意味著可以切片去取對(duì)應(yīng)的行,如取第2-4行:
15,、插入/刪除行列
① 插入行
在第3行處插入2行,插入后第3行開始(而不是第4行)為插入的數(shù)據(jù),。插入列為同樣的操作,,這里就不演示了。 ② 刪除行,。
可見,,第3、4行已經(jīng)被刪除(看最左邊的序號(hào),,而不是看rank列),。刪除列也是同樣操作。 16、凍結(jié)單元格sheet.freeze_panes = '單元格'
凍結(jié)了E5后,,當(dāng)頁面左右上下滑動(dòng)時(shí),,A、B,、C,、D列以及1、2,、3,、4行都不會(huì)動(dòng),方便觀看表頭等,。 至于如何解凍,,小編也想到過這個(gè)問題,但是沒有找到答案(找到有的說凍結(jié)填A(yù)1的,,或者填None的,但是我試過不太行,,因?yàn)榇蜷_文件會(huì)出現(xiàn)提示需要修復(fù)文件之類的),,等到小編找到答案后,再修改文章,,和大家分享,!也希望知道如何解凍的小伙伴在下方留言,幫助到更多的人,。 17,、移動(dòng)單元格區(qū)域sheet.move_range(cell_range, rows=0, cols=0, translate=False)
可全程只看左上角的單元格,如把D2移到了A7,,就是向左移動(dòng)了3列,,向下移動(dòng)了5行。移動(dòng)超出范圍會(huì)報(bào)錯(cuò),。 如果沒有替換到單元格,,那么很有可能是你的openpyxl庫不是最新的。 18、合并單元格sheet.merge_cells(range_string=None, start_row=None, start_column=None, end_row=None, end_column=None)
19、寫入公式
寫入公式是直接在''或者""中寫公式即可,。至于代碼中有兩行都可以,,如果不行,試試另一行,,按道理結(jié)果是一樣的(目前兩行的結(jié)果都一樣,,沒遇到過不行的)。公式單元格的讀取也和普通單元格一樣,,具體查看第九點(diǎn)獲取單元格的值,。 寫入公式也挺有趣的一個(gè)函數(shù),如用于求和的 "=sum(A1:B1)" 等,,更多功能自己去思考產(chǎn)生,,一個(gè)功能的誕生并不是只為了解決一個(gè)問題的,而是經(jīng)過靈活運(yùn)用去解決很多問題,。 說到這里,,想到了前面第四點(diǎn)讀取excel的一個(gè)點(diǎn):data_only。如果讀取excel時(shí)假如了該參數(shù),,那么原來excel里含有的公式都不是公式了,,變成了一個(gè)值。如上面的L2單元格,,原本意義是 "=D2&E2" ,,但設(shè)置了data_only的讀取模式后,它就只是 "鐘睒睒先生"幾個(gè)字,,不再是一個(gè)公式了,。 20、空值,、缺失值判斷這里我們的sheet表的L2單元格的沒有東西的,。輸出L2的值及格式如下:
這個(gè)NoneType格式是python內(nèi)置的空值的格式,并非字符串,。所以我們可以通過判斷單元格的值是否為None來判斷這個(gè)單元格是否是缺值的,。
注意這個(gè)None,用于python內(nèi)置缺失值的含義時(shí)是不需要加""的,,如果加了,,那就是判斷該單元格是不是一個(gè)字符串了,,如M2:
21、設(shè)置單元格的字體格式Font(name=None, sz=None, b=None, i=None, charset=None, u=None, strike=None, color=None, scheme=None, family=None, size=None, bold=None, italic=None, strikethrough=None, underline=None, vertAlign=None, outline=None, shadow=None, condense=None, extend=None)
用得最多的是這6個(gè)字體屬性,,其他如果生活中需要的話可以網(wǎng)上馬上搜,,很快的,比在我文章里找快,。
給 font屬性賦值 font對(duì)象即可,。如下,對(duì)A1單元格的字體格式進(jìn)行更改: 22,、設(shè)置單元格的對(duì)齊方式Alignment(horizontal=None, vertical=None, textRotation=0, wrapText=None, shrinkToFit=None, indent=0, relativeIndent=0, justifyLastLine=None, readingOrder=0, text_rotation=None, wrap_text=None, shrink_to_fit=None, mergeCell=None)
同樣,知道這兩個(gè)就可以了,,其他需要的再搜,。可以這樣記:h是 "橫" 的首字母,,橫向,;v像一個(gè)山溝,很深,,豎向,。
D1單元格已經(jīng)被左對(duì)齊。 23,、設(shè)置行高列寬
如果想要對(duì)所有行或者列進(jìn)行設(shè)置行高列寬,,可以使用for循環(huán),加上前面所以學(xué)的最大最小行列的獲取等知識(shí),,綜合運(yùn)用,,做出讓自己滿意的表格。 24,、關(guān)閉文件
關(guān)閉文件可以釋放內(nèi)存,,加快下個(gè)文件的運(yùn)行時(shí)間,。如把一個(gè)sheet表按照班級(jí)拆分成多個(gè)excel文件時(shí),每完成一個(gè)班級(jí)文件就關(guān)閉,,不會(huì)拖延下一個(gè)文件的寫入速度,。 結(jié)尾本篇開頭說過openpyxl 的優(yōu)缺點(diǎn),也和pandas作了對(duì)比,,各有春秋,。pandas更偏向于大數(shù)據(jù)的批量處理以及數(shù)據(jù)分析、機(jī)器學(xué)習(xí)等,,在pandas導(dǎo)出到excel之前,,無法對(duì)excel 的格式進(jìn)行設(shè)置,必須先導(dǎo)出為文件,,再用openpyxl 去調(diào)格式,。 不知各位小伙伴有沒有試過需要把一整列數(shù)據(jù)區(qū)進(jìn)行處理,如改格式,,+某個(gè)數(shù),,條件+值等呢,此類操作對(duì)于openpyxl來說太復(fù)雜,,如果用pandas進(jìn)行處理,,可能就幾行代碼。對(duì)于一個(gè)sheet拆分成多個(gè)sheet時(shí),,openpyxl也是麻煩透頂,,先全部遍歷,把它們?nèi)夸浫胱值?,再一一取值?chuàng)建sheet,,太麻煩啦,一頓操作下來幾十行代碼,,但是對(duì)于pandas來說,,可能都不用10行代碼就完成了。 大家如果對(duì)pandas感興趣,,大家可以自學(xué)起來了,,這個(gè)庫功能太多太復(fù)雜,需要互相鼓勵(lì),,相互加油,。 本文excel文件:鏈接:https://pan.baidu.com/s/1vjijcga5xlq2y36H30bFIQ?pwd=vffz |
|