99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁(yè)精彩閱讀聊聊python辦公自動(dòng)化之Excel(中)
聊聊python辦公自動(dòng)化之Excel(中)
2020-10-30
收藏

作者:星安果?

來(lái)源:AirPython

上一篇python辦公自動(dòng)化之Excel(上)文章中,我們聊到使用?xlrd、xlwt、xlutils 這一組合操作Excel 的方法。本篇文章將繼續(xù)聊另外一種方式,即:openpyxl。

不得不說(shuō),openpyxl 更強(qiáng)大!它支持?xlsx?格式的表格文件,并且支持 Numpy、Pandas 等包,可用于繪制圖表。

準(zhǔn)備:首先,我們需要安裝依賴(lài)包。

#?安裝依賴(lài)包
pip3?install?openpyxl

讀取數(shù)據(jù):使用 openpyxl 中的?load_workbook(filepath)?加載本地一個(gè) Excel 文件,返回結(jié)果是一個(gè)工作簿對(duì)象。

import?openpyxl

#?加載本地的Excel文件
wb?=?openpyxl.load_workbook(file_path)

利用工作簿對(duì)象,可以獲取所有的 Sheet 名稱(chēng)及 Sheet 列表。

def?get_all_sheet_names(wb):
????"""
????獲取所有sheet的名稱(chēng)
????:param?wb:
????:return:
????"""
????#?sheet名稱(chēng)列表
????sheet_names?=?wb.sheetnames
????return?sheet_names


def?get_all_sheet(wb):
????"""
????獲取所有的sheet
????:param?wb:
????:return:
????"""
????#?sheet名稱(chēng)列表
????sheet_names?=?get_all_sheet_names(wb)

????#?所有sheet
????sheets?=?[]
????for?sheet_name?in?sheet_names:
????????sheet?=?wb[sheet_name]
????????sheets.append(sheet)

????return?sheets

工作簿對(duì)象提供了?active?屬性,用于快速獲取當(dāng)前選擇的 Sheet。

def?get_current_sheet(wb):
????"""
????獲取當(dāng)前選擇的sheet,默認(rèn)是最后一個(gè)sheet
????:param?wb:
????:return:
????"""
????#?當(dāng)前選中的sheet
????current_sheet?=?wb.active

????return?current_sheet

另外,也可以通過(guò)?Sheet 名稱(chēng)去獲取某一個(gè)特定的 Sheet 對(duì)象。

def?get_sheet_by_name(wb,?sheet_name):
????"""
????通過(guò)sheetname去查找某一個(gè)sheet
????:param?wb:
????:param?sheet_name:
????:return:
????"""
????sheet_names?=?get_all_sheet_names(wb)
????if?sheet_name?in?sheet_names:
????????result?=?wb[sheet_name]
????else:
????????result?=?None
????return?result

使用?sheet.max_row?和?sheet.max_column?可以獲取當(dāng)前 Sheet 中的數(shù)據(jù)行數(shù)和列數(shù)。

def?get_row_and_column_num(sheet):
????"""
????獲取sheet的行數(shù)和列數(shù)
????:param?sheet:
????:return:
????"""
????#?行數(shù)
????row_count?=?sheet.max_row
????#?列數(shù)
????column_count?=?sheet.max_column

????return?row_count,?column_count

#?行數(shù)和列數(shù)
row_count,?column_count?=?get_row_and_column_num(sheet)
print('行數(shù)和列數(shù)分別為:',?row_count,?column_count)

openpyxl 提供 2 種方式來(lái)定位一個(gè)單元格,分別是:

  • 數(shù)字索引,從 1 開(kāi)始數(shù)字索引:行數(shù)字索引、列數(shù)字索引比如:row_index=1,column_index=1
  • 行和列組成的字符串索引字符串索引:列由字母組成 + 行索引比如:A1 對(duì)應(yīng)第一行、第一列的單元格。

并且,openpyxl.utils?提供了方法,便于?列索引?在兩者之間進(jìn)行轉(zhuǎn)換。

from?openpyxl.utils?import?get_column_letter,?column_index_from_string

def?column_num_to_str(num):
????"""
????Excel索引列從數(shù)字轉(zhuǎn)為字母
????:param?num:
????:return:
????"""
????return?get_column_letter(num)

def?column_str_to_num(str):
????"""
????Excel索引列,從字母轉(zhuǎn)為數(shù)字
????:param?str:
????:return:
????"""
????return?column_index_from_string(str)

單元格的獲取,同樣可以通過(guò)上面 2 種索引方式來(lái)獲取。

def?get_cell(sheet,?row_index,?column_index):
????"""
????獲取單元格
????:param?sheet:
????:param?row_index:
????:param?column_index:
????:return:
????"""
????#?openpyxl索引都是從1開(kāi)始計(jì)數(shù),這與xlrd有所不同
????#?獲取某一個(gè)單元格(二選一)
????#?比如:獲取A1單元格的數(shù)據(jù),即第一個(gè)行、第一列的數(shù)據(jù)
????#?cell_one?=?sheet['A1']
????cell_one?=?sheet.cell(row=row_index,?column=column_index)
????return?cell_one

在日常處理 Excel 數(shù)據(jù)過(guò)程中,可能需要判斷單元格數(shù)據(jù)類(lèi)型,而 openpyxl 并沒(méi)有提供現(xiàn)成的方法。這里,我們可以通過(guò)單元格對(duì)象的?value?屬性拿到值,接著使用?isinstance?方法判斷數(shù)據(jù)類(lèi)型。

def?get_cell_value_and_type(cell):
????"""
????獲取某一個(gè)cell的內(nèi)容及數(shù)據(jù)類(lèi)型
????:param?cell:
????:return:
????"""
????#?單元格的值
????cell_value?=?cell.value
????#?單元格的類(lèi)型
????cell_type?=?get_cell_value_type(cell_value)

????return?cell_value,?cell_type

def?get_cell_value_type(cell_value):
????"""
????獲取數(shù)據(jù)類(lèi)型
????:param?cell_value:
????:return:
????"""
????#?其中
????#?0:空
????# 1:數(shù)字
????# 2:字符串
????# 3:日期
????# 4:其他
????if?not?cell_value:
????????cell_type?=?0
????elif?isinstance(cell_value,?int)?or?isinstance(cell_value,?float):
????????cell_type?=?1
????elif?isinstance(cell_value,?str):
????????cell_type?=?2
????elif?isinstance(cell_value,?datetime.datetime):
????????cell_type?=?3
????else:
????????cell_type?=?4
????return?cell_type=

單獨(dú)獲取某一行[列]的數(shù)據(jù),可以使用下面的方式:

def?get_row_cells_by_index(sheet,?row_index):
????"""
????通過(guò)行索引,獲取某一行的單元格
????:param?row_index:
????:return:
????"""
????#?注意:第一列從1開(kāi)始
????row_cells?=?sheet[row_index]
????return?row_cells


def?get_column_cells_by_index(sheet,?column_index):
????"""
????通過(guò)列索引,獲取某一列的單元格
????"""
????#?數(shù)字轉(zhuǎn)為字母
????column_index_str?=?column_num_to_str(column_index)
????#?獲取某一列的數(shù)據(jù)
????column_cells?=?sheet[column_index_str]
????return?column_cells

需要注意的是,獲取某一行的數(shù)據(jù)需要傳入數(shù)字索引;而對(duì)于列數(shù)據(jù)的獲取,必須傳入字符串索引。和 Python 列表范圍取值類(lèi)似,openpyxl 同樣支持使用 : 符號(hào)拿到某個(gè)范圍內(nèi)的數(shù)據(jù)行[列]

def?get_rows_by_range(sheet,?row_index_start,?row_index_end):
????"""
????通過(guò)范圍去選擇行范圍
????比如:選擇第2行到第4行的所有數(shù)據(jù),返回值為元組
????:param?sheet:
????:param?row_index_start:
????:param?row_index_end:
????:return:
????"""
????rows_range?=?sheet[row_index_start:row_index_end]
????return?rows_range


def?get_columns_by_range(sheet,?column_index_start,?column_index_end):
????"""
????通過(guò)范圍去選擇列范圍
????比如:選擇第2列到第4列的所有數(shù)據(jù),返回值為元組
????:param?sheet:
????:param?column_index_start:
????:param?column_index_end:
????:return:
????"""
????columns_range?=?sheet[column_num_to_str(column_index_start):column_num_to_str(column_index_end)]
????return?columns_range

寫(xiě)入數(shù)據(jù)

要寫(xiě)入數(shù)據(jù)到 Excel 表格。首先,使用?openpyxl.Workbook()?創(chuàng)建一個(gè) Excel 工作簿對(duì)象。接著,使用工作簿對(duì)象的?create_sheet()?新建一個(gè) Sheet。

#?創(chuàng)建一個(gè)Excel工作簿
#?注意:每次新建一個(gè)Excel文件,都會(huì)默認(rèn)生成一個(gè)名稱(chēng)為【Sheet】的工作表Sheet
wb?=?openpyxl.Workbook()

#?創(chuàng)建一個(gè)新的sheet,默認(rèn)被插到尾部
#?new_sheet?=?wb.create_sheet('新的Sheet')
#?也可以通過(guò)第二個(gè)參數(shù):index來(lái)指定插入的位置
#?比如:插入到開(kāi)頭
new_sheet?=?wb.create_sheet('新的Sheet',?0)

默認(rèn)創(chuàng)建的 Sheet 被插入到最后一個(gè)位置,第 2 個(gè)參數(shù)可以指定 Sheet 插入的位置。

Sheet 標(biāo)簽的背景色同樣支持修改,使用?sheet_properties.tabColor?指定?RGB 顏色值。

比如,要設(shè)置某一個(gè) Sheet 的背景色為紅色,只需要先查詢(xún)到對(duì)應(yīng)的?Sheet,然后指定顏色值為 FF0000 即可。

def?set_sheet_bg_color(sheet,?rgb_value):
????"""
????設(shè)置Sheet標(biāo)簽的顏色
????:param?rgb_value:
????:return:
????"""
????#?設(shè)置Sheet底部按鈕的顏色(RRGGBB)
????sheet.sheet_properties.tabColor?=?rgb_value

?#?設(shè)置Sheet的背景色(紅色)
set_sheet_bg_color(new_sheet,?'FF0000')

openpyxl?支持行列數(shù)字索引、字符串索引以這 2 種方式寫(xiě)入數(shù)據(jù)到單元格中。

def?write_value_to_cell_with_num(sheet,?row_index,?column_index,?value):
????"""
????按行索引、列索引寫(xiě)入數(shù)據(jù)
????:param?shell:
????:param?row_index:?行索引
????:param?column_index:?列索引
????:param?value:
????:return:
????"""
????#?二選一
????sheet.cell(row=row_index,?column=column_index,?value=value)
????#?shell.cell(row=row_index,?column=column_index).value?=?value


def?write_value_to_cell_with_index_str(sheet,?index_str,?value):
????"""
????按字母位置,寫(xiě)入數(shù)據(jù)到對(duì)應(yīng)單元格
????:param?shell:
????:param?index_str:?字母對(duì)應(yīng)的單元格位置
????:param?value:
????:return:
????"""
????sheet[index_str]?=?value

在單元格中插入圖片也很簡(jiǎn)單,openpyxl 提供的?add_image()?方法。參數(shù)有 2 個(gè),分別是:圖片對(duì)象、單元格字符串索引。為了便于使用,我們可以將列索引進(jìn)行轉(zhuǎn)換,然后封裝成兩個(gè)插入圖片的方法。

from?openpyxl.drawing.image?import?Image

def?insert_img_to_cell_with_num(sheet,?image_path,?row_index,?column_index):
????"""
????往單元格中插入圖片
????:param?sheet:
????:param?image_path:
????:param?row_index:
????:param?column_index:
????:return:
????"""
????#?通過(guò)行索引、列索引,獲取到字母索引
????index_str?=?column_num_to_str(column_index)?+?str(row_index)
????insert_img_to_cell_with_str(sheet,?image_path,?index_str)

def?insert_img_to_cell_with_str(sheet,?image_path,?index_str):
????"""
????往單元格中插入圖片
????:param?sheet:
????:param?image_path:
????:param?index_str:
????:return:
????"""
????sheet.add_image((image_path),?index_str)

最后,調(diào)用工作簿對(duì)象的?save()?方法,將數(shù)據(jù)真實(shí)寫(xiě)入到 Excel 文件中。

#?注意:必須要寫(xiě)入,才能真實(shí)的保存到文件中
wb.template?=?False
wb.save('new.xlsx')

修改數(shù)據(jù)

修改數(shù)據(jù)包含:?jiǎn)卧駭?shù)據(jù)的修改、單元格樣式的修改。對(duì)于單元格數(shù)據(jù)的修改,只需要先讀取工作簿對(duì)象,查詢(xún)到要操作的 Sheet 對(duì)象,然后調(diào)用上面的方法修改單元格數(shù)據(jù),最后調(diào)用 save() 函數(shù)保存覆蓋即可。

def?modify_excel(self,?file_path):
????"""
????修改本地Excel文件中數(shù)據(jù)
????:param?file_path:
????:return:
????"""
????#?讀取本地Excel文件
????wb?=?openpyxl.load_workbook(file_path)

????#?讀取某一個(gè)sheet
????sheet?=?wb['第一個(gè)Sheet']
????print(sheet)

????#?直接修改某一個(gè)單元格的數(shù)據(jù)
????write_value_to_cell_with_num(sheet,?1,?1,?'姓名1')

????#?保存并覆蓋
????wb.save(file_path)

單元格樣式包含:字體樣式、單元格背景樣式、邊框樣式、對(duì)齊方式等。以常見(jiàn)的字體樣式、對(duì)齊方式為例。

首先,使用?openpyxl 中的?Font?類(lèi)創(chuàng)建一個(gè)對(duì)象,指定字體名稱(chēng)、字體大小、是否加粗、是否斜體、顏色、下劃線等。

from?openpyxl.styles?import?Font

#?字體格式
#?指定字體類(lèi)型、大小、是否加粗、顏色等
font0?=?Font(name='Calibri',
?????????????size=20,
?????????????bold=False,
?????????????italic=False,
?????????????vertAlign=None,??
?????????????underline='none',?
?????????????strike=False,
?????????????color='FF00FF00')

接著,構(gòu)建一個(gè)?Alignment?對(duì)象,指定單元格的對(duì)齊方式。

from?openpyxl.styles?import?Font,Alignment

#?單元格對(duì)齊方式
alignment0?=?Alignment(horizontal='center',
???????????????????????vertical='bottom',
???????????????????????text_rotation=0,
???????????????????????wrap_text=False,
???????????????????????shrink_to_fit=False,
???????????????????????indent=0)

最后,使用單元格對(duì)象的?font/alignment 屬性,將字體樣式和對(duì)齊方式設(shè)置進(jìn)去即可。

#?設(shè)置屬性樣式(字體、對(duì)齊方式)
sheet['A1'].font?=?font0
sheet['A1'].alignment?=?alignment0

6. 進(jìn)階用法

接下來(lái),聊聊幾個(gè)常用的進(jìn)階用法:

1、獲取可見(jiàn)及隱藏的 Sheet

通過(guò)判斷 Sheet 對(duì)象的?sheet_state?屬性值,可以判斷當(dāng)前 Sheet 是顯示還是隱藏。當(dāng)值為?visible?時(shí),代表 Sheet 是顯示的。當(dāng)值是?hidden?時(shí),代表這個(gè) Sheet 被隱藏了。

def?get_all_visiable_sheets(wb):
????"""
????獲取工作簿中所有可見(jiàn)的sheet
????:param?wb:
????:return:
????"""
????return?[sheet?for?sheet?in?get_all_sheet(wb)?if?sheet.sheet_state?==?'visible']


def?get_all_hidden_sheets(wb):
????"""
????獲取工作簿中所有隱藏的sheet
????:param?wb:
????:return:
????"""
????return?[sheet?for?sheet?in?get_all_sheet(wb)?if?sheet.sheet_state?==?'hidden']

2、獲取隱藏/顯示的行索引列表、列索引列表

受限于篇幅,這里以獲取所有顯示/隱藏的行索引列表為例,遍歷 Sheet 對(duì)象的?row_dimensions?屬性值,通過(guò)判斷行屬性的?hidden?值,判斷當(dāng)前行是否隱藏或顯示。

def?get_all_rows_index(sheet,?hidden_or_visiable):
????"""
????獲取所有隱藏/顯示的行
????:param?hidden_or_visiable:??True:隱藏;False:顯示
????:param?sheet:
????:return:
????"""
????#?遍歷行
????#?隱藏的索引
????hidden_indexs?=?[]

????#?所有隱藏的行索引
????for?row_index,?rowDimension?in?sheet.row_dimensions.items():
????????if?rowDimension.hidden:
????????????hidden_indexs.append(row_index)

????#?所有顯示的行索引
????visiable_indexs?=?[index?+?1?for?index?in?range(get_row_and_column_num(sheet)
    [0])?if?index?+?1?not?in?hidden_indexs]

????#?隱藏或者顯示的行索引列表
????return?hidden_indexs?if?hidden_or_visiable?else?visiable_indexs、

3、獲取單元格字體顏色及單元格背景顏色

單元格對(duì)象的?font.color.rgb、fill.fgColor.rgb?屬性值分別代表字體顏色值、單元格背景顏色。

def?get_cell_font_color(sheet,?row_index,?column_index):
????"""
????獲取單元格字體的顏色
????:param?sheet:
????:param?row_index:行索引
????:param?column_index:列索引
????:return:
????"""
????cell_color?=?sheet.cell(row_index,?column_index).font.color
????if?cell_color:
????????return?sheet.cell(row_index,?column_index).font.color.rgb
????else:
????????#?顏色不存在,可能單元格沒(méi)有數(shù)據(jù)
????????return?None

def?get_cell_bg_color(sheet,?row_index,?column_index):
????"""
????獲取單元格背景的顏色
????:param?sheet:
????:param?row_index:行索引
????:param?column_index:列索引
????:return:
????"""
????return?sheet.cell(row_index,?column_index).fill.fgColor.rgb

?最后

可以發(fā)現(xiàn),openpyxl 相比 xlrd/xlwt,提供了大量實(shí)用的 API,功能更強(qiáng)大,并且完美支持 xlsx!


 

——熱門(mén)課程推薦:

想從事業(yè)務(wù)型數(shù)據(jù)分析師,您可以點(diǎn)擊>>>“數(shù)據(jù)分析師”了解課程詳情;

想從事數(shù)據(jù)分析師,您可以點(diǎn)擊>>>“大數(shù)據(jù)就業(yè)”了解課程詳情;

想成為人工智能工程師,您可以點(diǎn)擊>>>“人工智能就業(yè)”了解課程詳情;

想了解Python數(shù)據(jù)分析,您可以點(diǎn)擊>>>“Python數(shù)據(jù)分析師”了解課程詳情;

想咨詢(xún)互聯(lián)網(wǎng)運(yùn)營(yíng),你可以點(diǎn)擊>>>互聯(lián)網(wǎng)運(yùn)營(yíng)就業(yè)班”了解課程詳情;

想了解更多優(yōu)質(zhì)課程,請(qǐng)點(diǎn)擊>>>

數(shù)據(jù)分析咨詢(xún)請(qǐng)掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢(xún)
客服在線
立即咨詢(xún)
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對(duì)象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶(hù)后臺(tái)檢測(cè)極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說(shuō)明請(qǐng)參見(jiàn):http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請(qǐng)輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請(qǐng)輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }