1. 程式人生 > >python修改已存在的xlsx件--OpenPyXL

python修改已存在的xlsx件--OpenPyXL

python提供了很多修改excel的模組,包括xlsxWriter、xlrd&xlwt、openPyXL、Microsoft Excel API、Pandas等,其中

xlsxWriter:只支援新建excel和向excel中寫入資料,並不支援對已有excel的讀取和修改,只能從零開始,功能很強大,支援大檔案的寫入,速度還比較多;適合的場景:需要建立xlsx檔案,不需要讀,且資料量大;

xlrd&xlwt&xlutils:對xls檔案的讀寫和其他很多全面的功能,但是對xlsx的excel支援很差,經過這三個模組修改過的xlsx檔案無法開啟,顯示已損壞(不知道有沒有解決方法);適用的場景:要讀取xls和xlsx檔案中的值,最後生成xls檔案,需要的功能不是很複雜可以考慮使用該種方法;
參考文件:https://blog.csdn.net/u013045749/article/details/49910695

OpenPyXL:較好的支援對xlsx檔案的修改,功能比較強大,適用於需要處理XLSX檔案,需要修改XLSX檔案中的值,最後生成xlsx。openpyxl(可讀寫excel表)專門處理Excel2007及以上版本產生的xlsx檔案,xls和xlsx之間轉換容易

注意:如果文字編碼是“gb2312” 讀取後就會顯示亂碼,請先轉成Unicode。

官網上最推薦的是openpyxl:

綜上,所以選擇使用OpenPyX來做一個修改excel的小程式。

OpenPyXL的官網參考:
https://openpyxl.readthedocs.io/en/latest/usage.html
https://openpyxl.readthedocs.io/en/stable/

1、OpenPyXL模組的安裝

pip install openpyxl

2、快速實現xlsx檔案的單元格修改

# -*- coding: utf-8 -*-
from openpyxl import load_workbook
file_home = 'C:\\files\\openpyxs.xlsx'
wb = load_workbook(filename= file_home)
sheet_ranges = wb['Sheet1']
print(sheet_ranges['A1'].value)
ws = wb['Sheet1'] //根據Sheet1這個sheet名字來獲取該sheet
ws["A1"] = 'LJK5679842'   //修改A1的值為LJK5679842
ws['D6'] = 'LKJI66666666666666'  //修改D6的值為,其中D6-F6是合併後的單元格,修改資料需修改最左上角單元格資料,來替代整個merge單元格
wb.save(file_depart)    //儲存修改後的excel

3、OpenPyXL的學習

迭代所有的行:
#獲取表格所有行和列,兩者都是可迭代的
rows = ws.rows
columns = ws.columns
#迭代所有的行
for row in rows:
 line = [col.value for col in row]
 print line
#通過座標讀取值
print ws.cell('A1').value # A表示列,1表示行
print ws.cell(row=1, column=1).value

新建excel處理:

wb = Workbook()#建立工作簿 
ws = wb.active#啟用工作表 
ws1 = wb.create_sheet("Mysheet")#建立mysheet表 
ws.title = "New Title"#表明改為New Title 
ws.sheet_properties.tabColor = "1072BA"#顏色 
ws['A4'] = 4#賦值 
d = ws.cell(row=4, column=2, value=10)#給第4行第2列賦值為10
cell_range = ws['A1':'C2']#選擇單元格區域 
wb.save('test.xlsx')#儲存
append函式在文末新增多行資料:
# 新增一行,在文末
row = [1 ,2, 3, 4, 5]
ws.append(row)
 
# 附加多行,從第一列開始附加
rows = [
  ['Number', 'data1', 'data2'],
  [2, 40, 30],
  [3, 40, 25],
  [4, 50, 30],
  [5, 30, 10],
  [6, 25, 5],
  [7, 50, 10],
]

合併和拆分單元格

# 合併單元格, 往左上角寫入資料即可
sheet.merge_cells('B1:G1') # 合併一行中的幾個單元格
sheet.merge_cells('A1:C3') # 合併一個矩形區域中的單元格
合併後只可以往左上角寫入資料,也就是區間中:左邊的座標。
如果這些要合併的單元格都有資料,只會保留左上角的資料,其他則丟棄。換句話說若合併前不是在左上角寫入資料,合併後單元格中不會有資料。
以下是拆分單元格的程式碼。拆分後,值回到A1位置。

插入時間格式資料:

import datetime
#python 型別資料會被自動轉換
ws['A2'] = datetime.datetime.now()
#儲存修改
wb.save("sample.xlsx")
獲取一個單元格的資料:
c = ws['A4']
c = ws.cell('A4') 
d = ws.cell(row = 4, column = 2)  
cell_range = ws['A1':'C2']  //一次獲取多個單元格的資料
ws['A1'] = 100  //寫入值

中文編碼的問題:

def gbk2utf(in_data , tag):  
    if 1 == tag:  
        return in_data.encode('gbk').decode('gbk')  
    elif 0 == tag:  
        return in_data.encode('gbk').decode('gbk').encode('utf8')  
openpyxl會自動轉換為不同的型別,有些表格中會有中文出現,就需要進行相應的轉碼。可以寫一個函式專門處理轉碼,需要時呼叫。當原始的excel檔案是gbk編碼時,就需要tag=0的方式去處理,

因為讀入後是gbk的編碼,需要先encode為gbk再decode為unicode,再encode為utf8,就可以顯示了。

4、openpyxl的使用

excel檔案的三個物件:
workbook: 工作簿,一個excel檔案包含多個sheet。
sheet:工作表,一個workbook有多個,表名識別,如“sheet1”,“sheet2”等。

cell: 單元格,儲存資料物件

操作Excel的一般場景:
    開啟或者建立一個Excel需要建立一個Workbook物件
    獲取一個表則需要先建立一個Workbook物件,然後使用該物件的方法來得到一個Worksheet物件
    如果要獲取表中的資料,那麼得到Worksheet物件以後再從中獲取代表單元格的Cell物件

open sheet:
通過名字:
    ws = wb["sheet_name"] 
    等同於 ws2 = wb.get_sheet_by_name('sheet_name')
    驗證命令ws is ws2 is ws3 輸出True
不知道名字用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讀第一個表

    活動表表名wb.get_active_sheet().title

單元格操作:

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')

特別注意:

get_sheet_names:獲取所有表格的名稱(新版已經不建議使用,通過Workbook的sheetnames屬性即可獲取)
例:

sheetnm = wb.worksheets
sheet = workbook.worksheets[0]
get_sheet_by_name:通過表格名稱獲取Worksheet物件(新版也不建議使用,通過workbook[‘sheet名‘]獲取);
例:ws = wb['Sheet1']


讀取的檔案路徑為中文時的處理方法:

a = "C:\\test\\test\\同址變更.xlsx"
file_name = unicode(a, "utf8")
或者是:file_name = a.decode("utf-8").encode("gbk")  #進行轉碼
另外,如果被讀取的excel中有圖片的話,就會報如下錯誤:

解決方法:

去掉excel中的圖片,或者是將openpyxl的版本回到5.0以下。。。。暫時沒找著好辦法

refer to:
https://stackoverflow.com/questions/48905957/cant-load-workbook-with-openpyxl-during-handling-of-the-above-exception-anoth

一些好的文件:
https://blog.csdn.net/cyjs1988/article/details/75041915?locationNum=8&fps=1
python 學習小組http://www.thinksaas.cn/group/show/368/page/4
官網:
    https://pypi.python.org/pypi/openpyxl
    http://openpyxl.readthedocs.io/en/default/
good:
    http://blog.csdn.net/suofiya2008/article/details/6284208
    http://blog.csdn.net/zzukun/article/details/49946147
    http://www.thinksaas.cn/topics/0/501/501962.html