1. 程式人生 > >最全總結 | 聊聊 Python 辦公自動化之 Excel(下)

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

![image](https://upload-images.jianshu.io/upload_images/1466987-53b1eeac548ed01b?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ## 1\. 前言 前面談到 Python 處理 Excel 檔案最常見的兩種方式,即:xlrd/xlwt、openpyxl ​其中, xlrd/xlwt 這一組合,xlrd 可以負責讀取資料,而 xlwt 則負責寫入資料,缺點是不支援 xlsx openpyxl 同時支援對 Excel 文件的讀取、寫入操作,缺點是不支援 xls 本篇文章將繼續聊聊 Python 操作 Excel 文件的其他幾種方式 ## 2\. xlsxwriter xlsxwriter 主要用於將資料、圖表寫入到 Excel 檔案中,可以配置使用較小的記憶體快速寫入資料 它的缺點是:無法讀取、修改已有的 Excel 檔案;如果需要讀取修改 Excel 檔案,只能搭配其他依賴庫使用,比如:xlrd 首先安裝 xlsxwriter 的依賴包 ``` # 安裝依賴包 pip3 install xlsxwriter ``` xlsxwriter 提供了 Workbook(filename) 方法,用於建立一個工作簿物件 使用工作簿物件的 add_worksheet(sheet_name) 函式,就可以在工作簿中建立 Sheet 了 ``` def create_workbook_and_worksheet(filename, worksheet_names): """ 建立工作簿和Sheet :param filename: 檔名稱 :param worksheet_names: sheet名稱列表 :return: """ wb = xlsxwriter.Workbook(filename) sheets = [] # 新增sheet for worksheet_name in worksheet_names: sheets.append(wb.add_worksheet(worksheet_name)) return wb, sheets ``` 接著,就可以往某個 Sheet 單元格中寫入資料了 如果需要定製單元格的樣式,比如:字型大小、字型、顏色、背景、是否加粗等,可以使用工作簿物件的 add_format() 方法建立一個樣式 ``` def create_format_styles(wb, format_stuyles): """ 建立一個樣式,包含:字型大小、字型、顏色、背景、是否加粗等 :param wb: :param format_stuyles: :return: """ return wb.add_format(format_stuyles) # 單元格字型樣式 self.title_style = {'bold': True, 'bg_color': '#B0C4DE', 'font_size': 10,'font_name': 'Microsoft yahei'} # 建立標題字型樣式 title_font_style = create_format_styles(self.wb, self.title_style) ``` Sheet 物件的 write(...) 函式用於向單元格中寫入資料,引數包含:行索引、列索引、值、字型樣式等 需要注意的是,預設 xlsxwriter 的行索引、列索引都是從 0 開始,即: 0 代表第一行 寫入資料的同時配置單元格樣式的寫法如下: ``` def write_to_cell(sheet, row_index, column_index, value, format_styles=None): """ 往單元格中寫入資料 :param row_index: 行索引,1:第一行 :param column_index: 列索引,1:第一列 :param format_styles 字型樣式 :return: """ if row_index < 1 or column_index < 1: print('引數輸入不正確,寫入失敗!') else: # 注意:預設xlsxwriter的行索引、列索引從0開始 sheet.write(row_index - 1, column_index - 1, value, format_styles) # 往worksheet中寫入資料 # 第一行 write_to_cell(self.current_sheet, 1, 1, "姓名", title_font_style) write_to_cell(self.current_sheet, 1, 2, "年齡", title_font_style) # 第二行 write_to_cell(self.current_sheet, 2, 1, 'xingag') write_to_cell(self.current_sheet, 2, 2, 23) ``` xlsxwriter 同樣支援在單元格中插入圖片,包含:本地圖片和網路圖片 使用的方法是:insert_image() 引數包含:單元格行索引(索引從 0 開始)、單元格列索引、圖片檔案、可選引數(圖片位置、縮放、url 超連結、image_data 圖片位元組流等) 以插入一張網路圖片為例 首先,定義一個圖片展示可選引數,指定圖片的縮放比、url 超連結 ``` def create_image_options(x_offset=0, y_offset=0, x_scale=1, y_scale=1, url=None, tip=None, image_data=None, positioning=None): """ 插入圖片的引數配置 包含:偏移量、縮放比、網路圖片連結、超連結、懸停提示燈 :param x_offset: :param y_offset: :param x_scale: :param y_scale: :param url: :param tip: :param image_data: :param positioning: :return: """ image_options = { 'x_offset': x_offset, 'y_offset': y_offset, 'x_scale': x_scale, 'y_scale': y_scale, 'url': url, 'tip': tip, 'image_data': image_data, 'positioning': positioning, } return image_options image_options = create_image_options(x_scale=0.5, y_scale=0.5, url='https://www.jianshu.com/u/f3b476549169') ``` 接著,將網路圖片轉為位元組流 ``` from io import BytesIO import ssl def get_image_data_from_network(url): """ 獲取網路圖片位元組流 :param url: 圖片地址 :return: """ ssl._create_default_https_context = ssl._create_unverified_context # 獲取網路圖片的位元組流 image_data = BytesIO(urlopen(url).read()) return image_data ``` 最後,將圖片插入到單元格中 ``` def insert_network_image(sheet, row_index, column_index, url, filepath, image_options=None): """ 插入網路圖片 :param sheet: :param row_index: :param column_index: :param url: :param filepath: :param image_options: :return: """ if row_index < 1 or column_index < 1: return "引數輸入有誤,插入失敗!" # 獲取圖片位元組流 image_data = get_image_data_from_network(url) if image_options: image_options['image_data'] = image_data print(image_options) sheet.insert_image(row_index - 1, column_index - 1, filepath, image_options) insert_network_image(self.current_sheet, 1, 1, url, '1.png', image_options4) ``` 使用 set_column() 方法可以設定列寬 和 openpyxl 類似,有 2 種使用方式,分別是:字串索引、列索引數字索引 ``` def set_column_width(sheet, index_start, index_end, width): """ 設定列寬 :param sheet: :param index_start: 開始位置,從1開始 :param index_end: 結束位置 :param width: 寬度 :return: """ # 方式二選一 # self.current_sheet.set_column('A:C', width) # 預設0代表第一列 sheet.set_column(index_start - 1, index_end - 1, width) # 設定列寬度 # 設定第1列到第3列的寬度為:100 set_column_width(self.current_sheet, 1, 3, 100) ``` 行高使用 set_row() 方法,傳入行索引和高度即可 ``` def set_row_height(sheet, row_index, height): """ 設定行高 :param sheet: :param row_index: 行索引,從1開始 :param height: :return: """ sheet.set_row(row_index - 1, height) # 設定行高 set_row_height(self.current_sheet, 1, 50) set_row_height(self.current_sheet, 2, 100) ``` 寫入資料完畢之後,將工作簿關閉,檔案會自動儲存到本地 ``` def teardown(self): # 寫入檔案,並關閉檔案 self.wb.close() ``` xlsxwriter 還支援插入圖表,比如:條形圖、柱狀圖、雷達圖等,受限於篇幅,這部分內容就不展開說明了 ## 3\. 其他方式 還有一種比較常見的方式是:xlwings xlwings 是一款開源免費的依賴庫,同時支援 Excel 檔案的讀取、寫入、修改 它功能非常強大,還可以和 Matplotlib、Numpy 和 Pandas 無縫連線,支援讀寫 Numpy、Pandas 資料型別;同時,xlwings 可以直接呼叫 Excel 檔案中 VBA 程式 需要注意的是,xlwings 依賴於 Microsoft Excel 軟體,所以使用 WPS 的使用者建議直接使用 openpyxl 官方文件: https://docs.xlwings.org/zh_CN/latest/quickstart.html 另外,還有一個操作 Excel 比較強大的方式,即:Pywin32 其中, Pywin32 相當於呼叫 Win 下的系統 API 來操作 Excel 檔案 優點是:可以處理複雜圖表的資料表 缺點也非常明顯,包含:速度慢、佔用 CPU 高,僅支援 Win 系統 ## 4\. 最後 綜合發現,xlrd/xlwt、openpyxl、xlsxwriter 基本上可以滿足大部分的日常 Excel 文件操作 要獲取全部原始碼,關注公眾號「 **AirPython** 」,後臺回覆「 **excel** 」即可獲得全部原始碼 如果你覺得文章還不錯,請大家 **點贊、分享、留言**下,因為這將是我持續輸出更多優質文章的最強動力! **推薦閱讀** [最全總結 | 聊聊 Python 辦公自動化之 Excel(上)](http://mp.weixin.qq.com/s?__biz=MzU1OTI0NjI1NQ==&mid=2247486752&idx=1&sn=bc58a3127bad72f2210817c3b4087801&chksm=fc1b73e0cb6cfaf6b1dbe8943d13a805d384ae74f043720a1d048c498405cc1ada93437f58ce&scene=21#wechat_redirect) [最全總結 | 聊聊 Python 辦公自動化之 Excel(中)](http://mp.weixin.qq.com/s?__biz=MzU1OTI0NjI1NQ==&mid=2247486789&idx=1&sn=e565569c17815a897ab6089f9c305d90&chksm=fc1b7385cb6cfa93c17632269677f60439e1738b23c7522eb75a5e8dedc61a5c44e0c681c447&scene=21#wechat_r