最全總結 | 聊聊 Python 辦公自動化之 Excel(上)

image

1. 前言

在我們日常工作中,經常會使用 Word、Excel、PPT、PDF 等辦公軟體

但是,經常會遇到一些重複繁瑣的事情,這時候手工操作顯得效率極其低下;通過 Python 實現辦公自動化變的很有必要

接下來的 一系列 文章,我將帶大家對 Python 辦公自動化做一個全面的總結,絕對的乾貨!

​2. 準備

使用 Python 操作 Excel 文件,常見的方式如下:

  • xlrd / xlwt

  • openpyxl

  • Pandas

  • xlsxwriter

  • xlwings

  • pywin32

xlrd 和 xlwt 是操作 Excel 文件最多的兩個依賴庫

其中,

xlrd 負責讀取 Excel 文件,xlwt 可以寫入數據到 Excel 文件

我們安裝這兩個依賴庫

# 安裝依賴庫
pip3 install xlrd 
pip3 install xlwt 

3. xlrd 讀取 Excel

使用 xlrd 中的 open_workbook(filepath) 打開本地一個 Excel 文件

import xlrd

# 打開文件,返回一個工作簿對象
wb = xlrd.open_workbook(file_path)

工作簿對象的 nsheets 屬性獲取 Sheet 數目,sheet_names() 方法返回所有 Sheet 名稱的列表

​# 統計sheet數量
sheets_num, sheets_names = wb.nsheets, wb.sheet_names()
print('sheet數量一共有:', sheets_num)
print('sheet名稱分別為:', sheets_names)

篩選出工作簿中的某一個 Sheet 有 2 種方式,分別是:

  • 通過 Sheet 名稱

  • 使用位置索引,從 0 開始

# 獲取某一個sheet
# 通過名稱或者索引獲取
sheet = wb.sheet_by_index(0)

# sheet = wb.sheet_by_name('第一個Sheet')
print(sheet)

每一個 sheet 對象都可以利用 name、nrows、ncols 獲取 Sheet 名稱、行數量、列數量

另外

row_values(index)、col_values(index) 分別用於獲取某一行或某一列的數據列表

# 獲取某一個sheet中,包含的行數量、列數量
sheet_name, sheet_row_count, sheet_column_count = sheet.name, sheet.nrows, sheet.ncols
print('當前sheet名稱為:', sheet_name, ",一共有:", sheet_row_count, "行;有:", sheet_column_count, "列")

# 單獨獲取某一行數據,索引從0開始
# 比如:獲取第2行數據
row_datas = sheet.row_values(1)
print('第2行數據為:', row_datas)

# 單獨獲取某一列數據,索引從0開始
# 比如:獲取第二列數據
column_datas = sheet.col_values(1)
print('第2列數據為:', column_datas)

單元格可以通過行索引、列索引,調用 cell(row_index,column_index) 函數獲取

需要注意的是,行索引和列索引都是從 0 開始,即:0 代表第一行

在 xlrd 中,單元格的數據類型包含 6 種,用 ctype 屬性對應關係如下:

  • 0  —  空(empty)

  • 1  —  字元串(string)

  • 2  —  數字(number)

  • 3  —  date(日期)

  • 4  —  boolean(布爾值)

  • 5  —  error(錯誤)

# 獲取某一個單元格的數據
# 比如:獲取第2行第1列的單元格的數據
one_cell = sheet.cell(1, 0)
# 單元格的值
cell_value = one_cell.value
print("單元格的值為:", cell_value)
# 單元格數據類型
cell_type = one_cell.
print("單元格數據類型為:", cell_type)

最後,如果要獲取當前 Sheet 所有單元格中的數據,可以通過遍歷所有行、列來操作

# 獲取所有單元格的值
print('表格中所有數據如下:')
for r in range(sheet.nrows):
    for i in range(sheet.ncols):
        print(sheet.cell(r, i).value)

4. xlwt 寫入 Excel

如果想實現將數據寫入到 Excel 中,xlwt 就很方便了

首先,使用 xlwt 的 Workbook() 方法創建一個工作簿對象

然後,使用工作簿對象的 add_sheet(sheetname) 方法新增 Sheet

import xlwt
​
sheetname = '第一個Sheet'

# 創建一個工作簿對象
wb = xlwt.Workbook()

# 添加Sheet,通過sheet名稱
sheet = wb.add_sheet(sheetname)

接著,通過 sheet 對象的 write() 方法,按照行索引和列索引,將數據寫入到對應單元格中去

# 將數據寫入到Sheet中
# 3個參數分別是:行索引(從0開始)、列索引(從0開始)、單元格的值
# 第一行第一列,寫入一個數據
# 寫入標題
for index, title in enumerate(self.titles):
    sheet.write(0, index, title)

# 寫入值
for index_row, row_values in enumerate(self.values):
    for index_column, column_value in enumerate(row_values):
        sheet.write(index_row + 1, index_column, column_value)

需要注意的是,最後必須調用工作簿的 save(filepath),才能在本地生成 Excel 文件

​# 保存文件
# 最後保存文件即可
wb.save(filepath)

5. 進階用法

接下來,聊聊幾個常用的進階用法

1、獲取所有可見的 Sheet

在讀取 Sheet 數據時,經常需要過濾隱藏的 Sheet

當 sheet 對象的 visibility 屬性值為 0 時,代表此 Sheet 在工作簿中是顯示的;否則被隱藏了

def get_all_visiable_sheets(self, wb):
    """
    獲取所有可見的sheet
    :param wb:
    :return:
    """
    return list(filter(lambda item: item.visibility == 0, wb.sheets()))

# 1、獲取所有可看見的sheet
sheet_visiable = self.get_all_visiable_sheets(wb)
print('所有可見的sheet包含:', sheet_visiable)

2、獲取 Sheet 可見行或列

某一個 Sheet 中,可能存在部分行、列被隱藏了

def get_all_visiable_rows(self, sheet):
    """
    獲取某一個sheet中,可見的行
    :param sheet:
    :return:
    """
    result = [index for index in range(sheet.nrows) if sheet.rowinfo_map[index].hidden == 0]
    return result

def get_all_visiable_columns(self, sheet):
    """
    獲取某一個sheet中,可見的列
    :param sheet:
    :return:
    """
    result = [index for index in range(sheet.ncols) if sheet.colinfo_map[index].hidden == 0]
    return result

3、獲取單元格的樣式

以獲取單元格字體顏色和背景為例

def get_cell_bg_color(self, wb, sheet, row_index, col_index):
    """
    獲取某一個單元格的背景顏色
    :param wb:
    :param sheet:
    :param row_index:
    :param col_index:
    :return:
    """
    xfx = sheet.cell_xf_index(row_index, col_index)
    xf = wb.xf_list[xfx]

    # 字體顏色
    font_color = wb.font_list[xf.font_index].colour_index
    # 背景顏色
    bg_color = xf.background.pattern_colour_index

    return font_color, bg_color

需要注意的是,使用 xlrd 讀取單元格的樣式,打開工作簿的時候需要顯式定義 formatting_info = True,否則會拋出異常

# 注意:必須設置formatting_info=True,才能正常獲取屬性
wb = xlrd.open_workbook(file_path, formatting_info=True)
sheet = wb.sheet_by_index(0)

6. 最後

搭配使用 xlrd、xlwt,基本上能完成大部分的工作,對於一些複雜的功能,比如:複製、分割、篩選等功能,可以用上 xlutils 這個依賴庫

需要指出的是,這個組合對 xlsx 的兼容性不太好;如果需要操作 xlsx 文件,需要先轉為 xls,然後再進行

我已經將文中全部源碼上傳到後台,關注公眾號「 AirPython 」後回復「 excel 」即可獲得全部源碼

如果你覺得文章還不錯,請大家 點贊、分享、留言下,因為這將是我持續輸出更多優質文章的最強動力!

推薦閱讀

聊聊 Python 數據處理全家桶(Mysql 篇)

聊聊 Python 數據處理全家桶(Sqlite 篇)

聊聊 Python 數據處理全家桶(Redis 篇)

聊聊 Python 數據處理全家桶(Memc 篇)

聊聊 Python 數據處理全家桶(Mongo 篇)

聊聊 Python 數據處理全家桶( 配置篇 )