一 . Python操作EXCEL庫的簡介
1.1 Python官方庫操作excel
Python官方庫一般使用xlrd庫來讀取Excel文件,使用xlwt庫來生成Excel文件,使用xlutils庫復制和修改Excel文件,這三個庫只支持到Excel2003。
1.2 第三方庫openpyxl介紹
第三方庫openpyxl(可讀寫excel表),專門處理Excel2007及以上版本產生的xlsx文件,xls和xlsx之間轉換容易。 注意:如果文字編碼是“gb2312” 讀取后就會顯示亂碼,請先轉成Unicode
本文將詳細介紹第三方庫openpyxl的基本用法
第三方庫openpyxl的安裝:
<1>下載路徑:https://pypi.python.org/pypi/openpyxl
<2>解壓到指定文件目錄:tar -xzvf openpyxl.tar.gz
<3>進入目錄,找到setup.py文件,執行命令:python3 setup.py install 如果報錯No module named setuptools 就使用命令“easy_install openpyxl”,easy_install for win32,會自動安裝setuptools; 或者直接用cmd命令:pip3 install openpyxl安裝
二. openpyxl庫基本操作總結
2.1 openpyxl 的基本操作
openpyxl中有三個不同層次的類,Workbook是對工作簿的抽象,Worksheet是對表格的抽象,Cell是對單元格的抽象,每一個類都包含了許多屬性和方法。
(1)Excel基本操作
操作Excel的一般場景:
a)打開或者創建一個Excel需要創建一個Workbook對象
b)獲取一個表則需要先創建一個Workbook對象,然后使用該對象的方法來得到一個Worksheet對象
c)如果要獲取表中的數據,那么得到Worksheet對象以后再從中獲取代表單元格的Cell對象
(2)Workbook對象知識點總結
一個Workbook對象代表一個Excel文檔,因此在操作Excel之前,都應該先創建一個Workbook對象。對於創建一個新的Excel文檔,直接進行Workbook類的調用即可,對於一個已經存在的Excel文檔,可以使用openpyxl模塊的load_workbook函數進行讀取,該函數包含多個參數,但只有filename參數為必傳參數。filename 是一個文件名,也可以是一個打開的文件對象。
創建workbook對象:
import openpyxl >>> wb = openpyxl.Workbook(‘hello.xlxs‘) >>> wb = openpyxl.load_workbook(‘file_name.xlxs‘)
注意:Workbook和load_workbook相同,返回的都是一個Workbook對象。
Workbook對象提供了很多屬性和方法,其中,大部分方法都與sheet有關,其所有屬性和方法如下:
['_sheets', '_pivots', '_active_sheet_index', 'defined_names', '_external_links', 'properties', 'security', '_Workbook__write_only', 'shared_strings', '_fonts', '_alignments', '_borders', '_fills', '_number_formats', '_protections', '_colors', '_cell_styles', '_named_styles', '_table_styles', 'loaded_theme', 'vba_archive', 'is_template', '_differential_styles', 'code_name', 'epoch', 'encoding', 'iso_dates', 'rels', 'calculation', 'views', '_data_only', '_read_only', '_keep_links', 'guess_types', 'template', '__module__', '__doc__', 'path', '__init__', '_setup_styles', 'read_only', 'data_only', 'write_only', 'keep_links', 'get_active_sheet', 'excel_base_date', 'active', 'create_sheet', '_add_sheet', 'remove', 'remove_sheet', 'create_chartsheet', 'get_sheet_by_name', '__contains__', 'index', 'get_index', '__getitem__', '__delitem__', '__iter__', 'get_sheet_names', 'worksheets', 'chartsheets', 'sheetnames', 'create_named_range', 'add_named_style', 'named_styles', 'get_named_ranges', 'add_named_range', 'get_named_range', 'remove_named_range', 'mime_type', 'save', 'style_names', 'copy_worksheet', 'close', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
Workbook提供的部分常用屬性如下:
- active:獲取當前活躍的Worksheet
- worksheets:以列表的形式返回所有的Worksheet(表格)
- read_only:判斷是否以read_only模式打開Excel文檔
- write_only:判斷是否以write_only模式打開Excel文檔
- encoding:獲取文檔的字符集編碼
- properties:獲取文檔的元數據,如標題,創建者,創建日期等
- sheetnames:獲取工作簿中的表(列表)

#常用屬性練習 workbook_path= os.path.join(CONFIG_PATH,'testdata.xlsx') wb = openpyxl.load_workbook(workbook_path) ws = wb.active print(ws)#<Worksheet "Sheet1"> ws_list=wb.worksheets print(ws_list)#[<Worksheet "Sheet1">, <Worksheet "Sheet2">, <Worksheet "Sheet3">] print(wb.read_only) #False print(wb.encoding)#utf-8 print(wb.write_only)#False print(wb.sheetnames)#['Sheet1', 'Sheet2', 'Sheet3'] print(wb.properties) #<openpyxl.packaging.core.DocumentProperties object> #Parameters: #creator='openpyxl', title=None, description=None, subject=None, identifier=None, language=None, created=datetime.datetime(2018, 8, 18, 2, 14, 50), # modified=datetime.datetime(2018, 8, 18, 5, 12, 7), lastModifiedBy='wuxiaoli', category=None, contentStatus=None, version=None, revision=None, # keywords=None, lastPrinted=None
Workbook提供的部分常用方法如下:
- get_sheet_names:獲取所有表格的名稱(新版已經不建議使用,通過Workbook的sheetnames屬性即可獲取)
- get_sheet_by_name:通過表格名稱獲取Worksheet對象(新版也不建議使用,通過Worksheet[‘表名‘]獲取)
- get_active_sheet:獲取活躍的表格(新版建議通過active屬性獲取)
- remove_sheet:刪除一個表格
- create_sheet:創建一個空的表格
- copy_worksheet:在Workbook內拷貝表格

#workbook常用方法練習 workbook_path= os.path.join(CONFIG_PATH,'testdata.xlsx') wb = openpyxl.load_workbook(workbook_path) sheet_names_list=wb.get_sheet_names()#['Sheet1', 'Sheet2', 'Sheet3'] ws1 = wb.get_sheet_by_name('Sheet2')#<Worksheet "Sheet2"> ws2 = wb.get_active_sheet()#<Worksheet "Sheet1"> ws3 = wb.create_sheet('text')#<Worksheet "text"> print(wb.sheetnames) #wb.remove_sheet(ws3) wb.copy_worksheet(from_worksheet=ws1)
(3)worksheet對象知識點總結
有了Worksheet對象以后,我們可以通過這個Worksheet對象獲取表格的屬性,得到單元格中的數據,修改表格中的內容。openpyxl提供了非常靈活的方式來訪問表格中的單元格和數據,Worksheet對象的所有屬性和方法如下:
['_WorkbookChild__parent', '_WorkbookChild__title', 'HeaderFooter', 'row_dimensions', 'column_dimensions', 'page_breaks', '_cells', '_charts', '_images', '_rels', '_drawing', '_comments', 'merged_cells', '_tables', '_pivots', 'data_validations', '_hyperlinks', 'sheet_state', 'page_setup', 'print_options', '_print_rows', '_print_cols', '_print_area', 'page_margins', 'views', 'protection', '_current_row', 'auto_filter', 'sort_state', 'paper_size', 'formula_attributes', 'orientation', 'conditional_formatting', 'legacy_drawing', 'sheet_properties', 'sheet_format', '__module__', '__doc__', '_rel_type', '_path', 'mime_type', 'BREAK_NONE', 'BREAK_ROW', 'BREAK_COLUMN', 'SHEETSTATE_VISIBLE', 'SHEETSTATE_HIDDEN', 'SHEETSTATE_VERYHIDDEN', 'PAPERSIZE_LETTER', 'PAPERSIZE_LETTER_SMALL', 'PAPERSIZE_TABLOID', 'PAPERSIZE_LEDGER', 'PAPERSIZE_LEGAL', 'PAPERSIZE_STATEMENT', 'PAPERSIZE_EXECUTIVE', 'PAPERSIZE_A3', 'PAPERSIZE_A4', 'PAPERSIZE_A4_SMALL', 'PAPERSIZE_A5', 'ORIENTATION_PORTRAIT', 'ORIENTATION_LANDSCAPE', '__init__', '_setup', 'sheet_view', 'selected_cell', 'active_cell', 'show_gridlines', 'show_summary_below', 'show_summary_right', 'vba_code', 'get_cell_collection', 'freeze_panes', 'add_print_title', 'cell', '_get_cell', '_add_cell', '__getitem__', '__setitem__', '__iter__', '__delitem__', 'min_row', 'max_row', 'min_column', 'max_column', 'calculate_dimension', 'dimensions', 'iter_rows', '_cells_by_row', 'rows', 'values', 'iter_cols', '_cells_by_col', 'columns', 'get_squared_range', 'get_named_range', 'set_printer_settings', 'add_data_validation', 'add_chart', 'add_image', 'add_table', 'add_pivot', 'merge_cells', '_clean_merge_range', 'merged_cell_ranges', 'unmerge_cells', 'append', '_move_cells', 'insert_rows', 'insert_cols', 'delete_rows', 'delete_cols', '_invalid_row', '_add_column', '_add_row', '_write', 'print_title_rows', 'print_title_cols', 'print_titles', 'print_area', '_id', '_default_title', '__repr__', 'parent', 'encoding', 'title', 'oddHeader', 'oddFooter', 'evenHeader', 'evenFooter', 'firstHeader', 'firstFooter', 'path', '__dict__', '__weakref__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
Worksheet提供的部分常用屬性如下:
- title:表格的標題
- dimensions:表格的大小,這里的大小是指含有數據的表格的大小,即:左上角的坐標:右下角的坐標
- max_row:表格的最大行
- min_row:表格的最小行
- max_column:表格的最大列
- min_column:表格的最小列
- rows:按行獲取單元格(Cell對象) - 生成器
- columns:按列獲取單元格(Cell對象) - 生成器
- freeze_panes:凍結窗格
- values:按行獲取表格的內容(數據) - 生成器
注意:freeze_panes,參數比較特別,主要用於在表格較大時凍結頂部的行或左邊的行。對於凍結的行,在用戶滾動時,是始終可見的,可以設置為一個Cell對象或一個端元個坐標的字符串,單元格上面的行和左邊的列將會凍結(單元格所在的行和列不會被凍結)。例如我們要凍結第一行那么設置A2為freeze_panes,如果要凍結第一列,freeze_panes取值為B1,如果要同時凍結第一行和第一列,那么需要設置B2為freeze_panes,freeze_panes值為none時 表示 不凍結任何列。
Workbook提供的部分常用方法如下:
- iter_rows:按行獲取所有單元格,內置屬性有(min_row,max_row,min_col,max_col)
- iter_columns:按列獲取所有的單元格
- append:在表格末尾添加數據
- merged_cells:合並多個單元格
- unmerged_cells:移除合並的單元格
(4)cell對象知識點總結
Cell對象比較簡單,常用的屬性如下:
- row:單元格所在的行
- column:單元格坐在的列
- value:單元格的值
- coordinate:單元格的坐標
(5)Excel基本操作總結

<1>openpyxl的三種最重要的數據結構 NULL空值:對應於python中的None,表示這個cell里面沒有數據。 numberic: 數字型,統一按照浮點數來進行處理。對應於python中的float。 string: 字符串型,對應於python中的unicode。 <2>Excel 文件的三個對象 workbook: 工作簿,一個excel工作簿包含多個sheet。 sheet:工作表,一個workbook有多個,表名識別,如“sheet1”,“sheet2”等。 cell: 單元格,存儲數據對象 <3>導入 from openpyxl import Workbook from openpyxl import load_workbook from openpyxl.styles import PatternFill, Border, Side, Alignment, Protection, Font, Color, Fill from openpyxl.styles import colors from openpyxl.styles import Fill,fills from openpyxl.formatting.rule import ColorScaleRule <4>加載workbook 加載workbook時注意openpyxl只支持xlsx格式,老版的xls格式需要其他方法去加載。 wb = load_workbook('file_name.xlsx')或wb = load_workbook(filename = r'file_namexlsx') <5>新建worksheet 新建工作表用函數create_sheet() create_sheet(title=None, index=None): """Create a worksheet (at an optional index). :param title: optional title of the sheet :type title: unicode :param index: optional position at which the sheet will be inserted :type index: int """ ws1 = wb.create_sheet() #默認插在最后 ws2 = wb.create_sheet(0) #插在開頭建表后默認名按順序,如sheet1,sheet2... ws.title = "New Title" #修改表名稱 簡化 ws2 = wb.create_sheet(title="sheet_name") <6>打開 worksheet 1)通過名字 ws = wb["sheet_name"] 等同於 ws2 = wb.get_sheet_by_name('sheet_name') 2)不知道名字用index sheet_names = wb.get_sheet_names() ws = wb.get_sheet_by_name(sheet_names[index])# index為0為第一張表 或者 ws =wb.active 等同於 ws = wb.get_active_sheet() #通過_active_sheet_index設定讀取的表,默認0讀第一個表 3) 獲取活動表表名wb.get_active_sheet().title <7>編輯單元格 1)讀寫單個單元格 c = ws['A4'] #read 等同於 c = ws.cell('A4') ws['A4'] = 4 #write #ws.cell有兩種方式,行號列號從1開始 d = ws.cell(row = 4, column = 2) #行列讀寫 d = ws.cell('A4') 寫入cell值 ws.cell(row = 4, column = 2).value = 'test') ws.cell(row = 4, column = 2, value = 'test') 2)讀寫多個單元格 cell_range = ws['A1':'C2']#讀取A1到C1單元格數據 get_cell_collection()#讀所有單元格數據 <8>獲取最大行和最大列 print(sheet.max_row) print(sheet.max_column) <9>獲取行和列的值 sheet.rows為生成器, 里面是每一行的數據,每一行又由一個tuple包裹。 sheet.columns類似,不過里面是每個tuple是每一列的單元格。 # 按行獲取值,返回值為A1, B1, C1這樣的順序 for row in sheet.rows: for cell in row: print(cell.value) # 按列獲取值,返回值為A1, A2, A3這樣的順序 for column in sheet.columns: for cell in column: print(cell.value) 上面的代碼就可以獲得所有單元格的數據。如果要獲得某行的數據呢?因sheet.rows是生成器類型,不能使用索引,但是轉換成list之后便可使用索引,如list(sheet.rows)[2]這樣就獲取到第三行的tuple對象。 for cell in list(sheet.rows)[2]: print(cell.value) 也可以通過iter_rows的參數min_row, max_row指定並獲取指定行內容,如下所示,獲取第二行表格的內容: for row in ws.iter_rows(min_row=2, max_row=2,): line = [cell.value for cell in row] print(line) 此外可使用方法ws.iter_rows()逐行讀取數據 ws.iter_rows(range_string=None, row_offset=0, column_offset=0): range-string(string)-單元格的范圍:例如('A1:C4') row_offset-添加行 column_offset-添加列 # 返回一個生成器, 注意取值時要用value,例如: from openpyxl import load_workbook from constant.constant import CONFIG_PATH import os.path test_data = os.path.join(CONFIG_PATH,'testdata.xlsx') wb = load_workbook(test_data) ws = wb.active ws.title = 'testdata.xlsx' for row in ws.iter_rows('A1:C2'): for cell in row: print(cell.value) <10>獲取任意區間的值 法1.使用range函數 可以使用range函數,下面的寫法,獲得了以A1為左上角,B3為右下角矩形區域的所有單元格。注意range從1開始的,因為在openpyxl中為了和Excel中的表達方式一致,並不和編程語言的習慣以0表示第一個值。 workbook_path= os.path.join(CONFIG_PATH,'testdata.xlsx') wb = openpyxl.load_workbook(workbook_path) ws = wb.get_sheet_by_name(name='Sheet1') for i in range(1, 4): for j in range(1, 3): print(ws.cell(row=i, column=j)) #out #<Cell 'Sheet1'.A1> #<Cell 'Sheet1'.B1> #<Cell 'Sheet1'.A2> #<Cell 'Sheet1'.B2> #<Cell 'Sheet1'.A3> #<Cell 'Sheet1'.B3> 法2.使用切片,如sheet['A1':'B3'],返回一個tuple,該元組內部還是元組,由每行的單元格構成一個元組。 workbook_path= os.path.join(CONFIG_PATH,'testdata.xlsx') wb = openpyxl.load_workbook(workbook_path) ws = wb.get_sheet_by_name(name='Sheet1') for row_cell in ws['A1':'B3']: for cell in row_cell: print(cell) #out #<Cell 'Sheet1'.A1> #<Cell 'Sheet1'.B1> #<Cell 'Sheet1'.A2> #<Cell 'Sheet1'.B2> #<Cell 'Sheet1'.A3> #<Cell 'Sheet1'.B3> for cell in sheet['A1':'B3']: print(cell) #out #(<Cell 'Sheet1'.A1>, <Cell 'Sheet1'.B1>) #(<Cell 'Sheet1'.A2>, <Cell 'Sheet1'.B2>) #(<Cell 'Sheet1'.A3>, <Cell 'Sheet1'.B3>)

<11>根據字母獲得列號,根據列號返回字母 from openpyxl.utils import get_column_letter, column_index_from_string # 根據列的數字返回字母 print(get_column_letter(2)) # B # 根據字母返回列的數字 print(column_index_from_string('D')) # 4 <12>寫單元格 # 直接給單元格賦值就行 sheet['A1'] = 'good' # 利用公式在B9處寫入平均值 sheet['B9'] = '=AVERAGE(B2:B8)' #注意:如果是讀取,需要加上data_only=True,這樣讀到B9返回的才是數字,如果不加這個參數,返回的將是公式本身'=AVERAGE(B2:B8)' <13>使用append函數寫數據 append函數可以一次添加多行數據,從第一行空白行開始(下面都是空白行)寫入。 ws.append(iterable) #添加一行到當前sheet的最底部(即逐行追加從第一行開始) iterable必須是list,tuple,dict,range,generator類型的。 1,如果是list,將list從頭到尾順序添加。 2,如果是dict,按照相應的鍵添加相應的鍵值。 ws.append([‘This is A1’, ‘This is B1’, ‘This is C1’]) ws.append({‘A’ : ‘This is A1’, ‘C’ : ‘This is C1’}) ws.append({1 : ‘This is A1’, 3 : ‘This is C1’}) # 添加一行如下: row = [1 ,2, 3, 4, 5] sheet.append(row)
2.2 openpyxl練習
(1)Excel的讀取操作練習
練習表格內容如下

import openpyxl if __name__=='__main__': wb = openpyxl.load_workbook(r'D:\pythonstudy\2018-08-18.xlsx') # 取第一張表 sheetnames = wb.sheetnames ws = wb[sheetnames[0]] # 顯示表名,表行數,表列數 print("Work Sheet Title:", ws.title) print("Work Sheet Rows:", ws.max_row) print("Work Sheet Cols:",ws.max_column) #獲取指定行的值,如第三行 row3_values = [] row3_cell_list = list(ws.rows)[2] for cell in row3_cell_list: row3_values.append(cell.value) print(row3_values)#output:['A3', 'B3', 'C3', 'D3'] #獲取所有行的數據 # 建立存儲數據的字典 data = {} # 獲取表格所有值 #法1: for i in range(0,ws.max_row): every_row_values = [] every_row_cell_list = list(ws.rows)[i] for cell in every_row_cell_list: every_row_values.append(cell.value) data[i+1]= every_row_values print(data) #{1: ['A1', 'B1', 'C1', 'D1'], 2: ['A2', 'B2', 'C2', 'D2'], 3: ['A3', 'B3', 'C3', 'D3'], 4: ['A4', 'B4', 'C4', 'D4'], 5: ['A5', 'B5', 'C5', 'D5'], # 6: ['A6', 'B6', 'C6', 'D6'], 7: ['A7', 'B7', 'C7', 'D7'], 8: ['A8', 'B8', 'C8', 'D8'], 9: ['A9', 'B9', 'C9', 'D9'], 10: ['A10', 'B10', 'C10', 'D10'], # 11: ['A11', 'B11', 'C11', 'D11']} #法2 for row in ws.rows: line = [cell.value for cell in row] print (line)#output:['A1', 'B1', 'C1', 'D1'],['A2', 'B2', 'C2', 'D2'], ['A3', 'B3', 'C3', 'D3'],['A4', 'B4', 'C4', 'D4'], ['A5', 'B5', 'C5', 'D5'],['A6', 'B6', 'C6', 'D6'],['A7', 'B7', 'C7', 'D7'],['A8', 'B8', 'C8', 'D8'],['A9', 'B9', 'C9', 'D9'],['A10', 'B10', 'C10', 'D10'],['A11', 'B11', 'C11', 'D11'] #獲取某個區間的值,例:獲得了以A3為左上角,C6為右下角矩形區域的所有單元格 #法1:使用range data1={} for i in range(2,6): every_row_values = [] every_row_cell_list = list(ws.rows)[i] for cell in every_row_cell_list: every_row_values.append(cell.value) data1[i+1]=every_row_values print(data1) #output{3: ['A3', 'B3', 'C3', 'D3'], 4: ['A4', 'B4', 'C4', 'D4'], 5: ['A5', 'B5', 'C5', 'D5'], 6: ['A6', 'B6', 'C6', 'D6']} #法2:使用切片 data_list = [] for row_cell in ws['A3':'C6']: every_row_value = [] for cell in row_cell: every_row_value.append(cell.value) data_list.append(every_row_value) print(data_list)#output:[['A3', 'B3', 'C3'], ['A4', 'B4', 'C4'], ['A5', 'B5', 'C5'], ['A6', 'B6', 'C6']]
(2)封裝一個讀取表格的類,實用於讀測試用例

#-*- coing=utf-8 -*- from openpyxl import load_workbook from constant.constant import CONFIG_PATH import os.path class ExcelReader(object): """ Read the contents of the excel file, Return list. example: The contents of the excel file: | A | B | C | | A1 | B1 | C1 | | A2 | B2 | C2 | print(ExcelReader(excel, title_line=True).data),output: [{A: A1, B: B1, C:C1}, {A:A2, B:B2, C:C2}] print(ExcelReader(excel, title_line=False).data),output: [[A,B,C], [A1,B1,C1], [A2,B2,C2]] You can specify sheet through index or name: example: ExcelReader(excel, sheet=2) ExcelReader(excel, sheet='testdata') """ def __init__(self, excel, sheet=0, title_line=True): if os.path.exists(excel): self.excel = excel else: raise FileNotFoundError('Excel file does not exist !') self.sheet = sheet self.title_line = title_line self._data = list() @property def data(self): if not self._data: workbook = load_workbook(self.excel) if type(self.sheet) not in [int, str]: raise TypeError('Please pass in <type int> or <type str>, not {0}'.format(type(self.sheet))) elif type(self.sheet) == int: sheetnames = workbook.sheetnames ws = workbook[sheetnames[self.sheet]] else: ws = workbook[self.sheet] if self.title_line: for row in ws.iter_rows(min_row=1, max_row=1, ): title = [cell.value for cell in row]# 首行為title for i in range(1, ws.max_row): every_row_cell_list = list(ws.rows)[i] every_row_value = [] for cell in every_row_cell_list: every_row_value.append(cell.value) self._data.append(dict(zip(title, every_row_value))) else: for row in ws.rows: self._data.append([cell.value for cell in row]) return self._data if __name__ == '__main__': test_data = os.path.join(CONFIG_PATH,'testdata.xlsx') reader = ExcelReader(test_data,sheet= 0,title_line=False) print(reader.data)
(3)Openpyxl常用操作的封裝

#-*- coing=utf-8 -*- from openpyxl import load_workbook from openpyxl.utils import get_column_letter, column_index_from_string from config.globalconfig import TEST_DATA_PATH import os.path class ExcelReader(object): def __init__(self, excel, sheet=0, title_line=True,column=None,row=None): """ :param excel: excel path,type=str :param sheet: sheet name or sheet sequence number,type = str or int :param title_line: title_line = True,return dic,title_line = False,return list :param column: Non essential parameter,type = int or str,int express column number,str express column field name of first line :param row: Non essential parameter,type = int,express row number """ if os.path.exists(excel): self.excel = excel else: raise FileNotFoundError('Excel file does not exist !') self.sheet = sheet self.title_line = title_line self.column = column self.row = row self._data = [] self._cell_data = str() self.workbook = load_workbook(self.excel) if type(self.sheet) not in [int, str]: raise TypeError('Please pass in <type int> or <type str>, not {0}'.format(type(self.sheet))) elif type(self.sheet) == int: sheetnames = self.workbook.sheetnames self.ws = self.workbook[sheetnames[self.sheet]] else: self.ws = self.workbook[self.sheet] @property def sheet_data(self): """ Read the contents of the excel file, Return list. example: The contents of the excel file: | A | B | C | | A1 | B1 | C1 | | A2 | B2 | C2 | print(ExcelReader(excel, title_line=True).data),output: [{A: A1, B: B1, C:C1}, {A:A2, B:B2, C:C2}] print(ExcelReader(excel, title_line=False).data),output: [[A,B,C], [A1,B1,C1], [A2,B2,C2]] You can specify sheet through index or name: example: ExcelReader(excel, sheet=2) ExcelReader(excel, sheet='testdata') """ if not self._data: if self.title_line: for row in self.ws.iter_rows(min_row=1, max_row=1, ): title = [cell.value for cell in row]# 首行為title for i in range(1, self.ws.max_row): every_row_cell_list = list(self.ws.rows)[i] every_row_value = [] for cell in every_row_cell_list: every_row_value.append(cell.value) self._data.append(dict(zip(title, every_row_value))) else: for row in self.ws.rows: self._data.append([cell.value for cell in row]) return self._data def column_letter(self): """Column number converted to letter form.""" if isinstance(self.column, (int)): return get_column_letter(self.column) # 數字轉換為字母 elif isinstance(self.column, (str)): for row in self.ws.iter_rows(min_row=1, max_row=1, ): columnFieldName = [cell.value for cell in row] if columnFieldName.count(self.column) == 1: # 相同字段名存在的個數 for index, cell in enumerate(columnFieldName): if cell == self.column: return get_column_letter(index + 1) elif columnFieldName.count(self.column) == 0: raise ValueError("Current sheet page '%s' no field name '%s' exists!" % (self.ws.title, self.column)) else: raise ValueError("Current sheet page'%s'include duplicate field name '%s'" % (self.ws.title, self.column)) else: raise TypeError("The column parameter type should be int or str, not '%s'" % (self.column.__class__)) @property def cell_data(self): if not self._cell_data: if not isinstance(self.row, (int)): raise TypeError("The row parameter type should be int instead of '%s'!" % (self.row.__class__)) column = self.column_letter() return self.ws[column + str(self.row)].value class ExcelWritter(ExcelReader): def __init__(self, excel, sheet=0, column=None,row=None,value=''): ExcelReader.__init__(self,excel,sheet=0) self.value = value self.column =column self.row = row def write_cell(self): if not isinstance(self.row, (int)): raise TypeError("The row parameter type should be int instead of '%s'!" % (self.row.__class__)) if not isinstance(self.value, (str)): raise TypeError("The value parameter type should be str instead of '%s'!" % (self.value.__class__)) column = self.column_letter() self.ws[column + str(self.row)].value = self.value self.workbook.save(self.excel)
(4)寫存在的xlsx文件,報錯:PermissionError: [Errno 13] Permission denied的解決辦法
此問題為文件被拒絕訪問,主要是該文件已經被打開了。關閉此excel文件后在執行excel的相關操作就ok了。
>>>>>>>>>>待續