python操作excel表格(xlrd/xlwt)以及表格的修改(OpenPyXL)


python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。

需要安裝這2個庫,安裝的方式有多重可以直接使用pip安裝(根據自己的需求安裝):

如pip安裝

pip3 install xlrd
pip3 install xlwt

讀excel-->xlrd

自己先建一個excel表格內容如下:

 

有上面的Excel表格知道里面有2個sheet,其中第一個sheet1有內容,sheet2沒有內容

下面是關於python對Excel讀的基本操作:

import xlwt, xlrd
from datetime import date, datetime

# 打開excel文件,創建一個workbook對象,book對象也就是fruits.xlsx文件,表含有sheet名
workbook = xlrd.open_workbook(r'C:\Users\PC\Desktop\sss.xlsx')
print(workbook.sheet_names())  # 得到一個列表里面的元素就是sheet的名字
# 上面執行的結果為['Sheet1', 'Sheet2']
print(workbook.sheets())  # 得到的是一個列表里面的元素就是每一個sheet對象
# 上面執行的結果為[<xlrd.sheet.Sheet object at 0x0000019BB9D915C0>, <xlrd.sheet.Sheet object at 0x0000019BB9D91128>]

sheet_name = workbook.sheet_names()[0]  # 從零開始,取第一個sheet的名字
sheet_obj = workbook.sheets()[0]  # 從零開始取第一個sheet對象
print(sheet_name, sheet_obj)
# 上面執行的結果為:Sheet1 <xlrd.sheet.Sheet object at 0x000001E620A7CBE0>

# 根據sheet索引或者名稱獲取sheet內容
rsheet = workbook.sheet_by_index(0)  # 取第一個工作簿根據索引
rsheet_name = workbook.sheet_by_name(sheet_name)  # 根據sheet的名字取第一個工作簿
print('rsheet_index', rsheet)
print('rsheet_name', rsheet_name)

# 獲取總行數,列數和名字根據sheet的內容也就是上面的rsheet或者rsheet_name
print(rsheet.nrows, rsheet.ncols, rsheet.name)
rows = rsheet.nrows
# 獲取總列數
cols = rsheet.ncols
# sheet名稱
sheet_name = rsheet.name

# 獲取整行和整列的值
rows2_values = rsheet.row_values(1)  # 獲取第二行內容,得到的是一個列表
cols3_values = rsheet.col_values(2)  # 獲取第三列內容,得到的是一個列表
print(rows2_values, cols3_values)
# ['小傑', 23.0, 33919.0, '鍵盤', '朋友'] ['出生日期', 33919.0, 33920.0, 33921.0, 33922.0, 33923.0, '暫無']

# 通過cell的位置坐標取得cell值的幾種方式
print('獲取第二行第一列的值', rsheet.cell(1, 0).value)
print('獲取第二行第一列的值', rsheet.cell_value(1, 0))
print('獲取第二行第一列的值', rsheet.row(1)[0].value)

# 獲取單元格內容的數據類型
print(rsheet.cell(1, 0).ctype)
View Code

 運行結果如下

 可以看到上面的日期這里列在表格中明明寫的是日期在這里是浮點數。那讓我們來解決這一個問題:

1、python讀取excel中單元格內容為日期的方式

python讀取excel中單元格的內容返回的有5種類型,即上面例子中的ctype:

ctype :  0 empty,1 string, 2 number, 3 date, 4 boolean, 5 error

即date的ctype=3,這時需要使用xlrd的xldate_as_tuple來處理為date格式,

先判斷表格的ctype=3時xldate才能開始操作。繼續上面的代碼:

#  關於單元格里面時間格式的轉換
print(rsheet.cell(2, 0).ctype)  # 結果為1(字符)
print(rsheet.cell(2, 1).ctype)  # 結果為2(數字)
print(rsheet.cell(2, 2).ctype)  # 結果為3(日期)
print(rsheet.cell(2, 3).ctype)  # 結果為1(字符)
print(rsheet.cell(2, 4).ctype)  # 結果為0(空值) 這個是因為合並單元格的原因

print(rsheet.cell(2, 2).value)  # 打印的是一個浮點數
# 結果為 33920.0
print(xlrd.xldate_as_tuple(rsheet.cell(2, 2).value, workbook.datemode))  # 轉化為一個我們能夠看得懂的元組
# 結果為 (1992, 11, 12, 0, 0, 0)

date_tuple = xlrd.xldate_as_tuple(rsheet.cell(2, 2).value, workbook.datemode)
date_time = date(*date_tuple[:3]).strftime('%Y/%m/%d')  # 轉換為正常的日期格式
print(date_time)
# 1992/11/12

# 有上面我們可以簡單地判斷是不是時間如果是時間就做轉換
row = 2  # 這個可以改成你想要的行數
col = 2  # 這個可以改成你想要的列數
if (rsheet.cell(row, col).ctype == 3):
    date_value = xlrd.xldate_as_tuple(rsheet.cell_value(rows, col), workbook.datemode)
    date_tmp = date(*date_value[:3]).strftime('%Y/%m/%d')

那么問題又來了,上面 rsheet.cell(2,4).ctype 返回的值是0,說明這個單元格的值是空值,明明是合並的單元格內容"好朋友",這個是我覺得這個包功能不完善的地方,如果是合並的單元格那么應該合並的單元格的內容一樣,但是它只是合並的第一個單元格的有值,其它的為空。

2、讀取合並單元格的內容:

這個是真沒技巧,只能獲取合並單元格的第一個cell的行列索引,才能讀到值,讀錯了就是空值。

即合並行單元格讀取行的第一個索引,合並列單元格讀取列的第一個索引,如上述,讀取行合並單元格"好朋友"和讀取列合並單元格"暫無"只能如下方式:

# 關於合並單元格里面里面的空值
# 如:
print(rsheet.cell(2, 4).ctype)  # 結果為0(空值) 這個是因為合並單元格的原因
# 明明這里是合並單元格應該顯示好朋友的

# 讀取合並單元格的內容
print(rsheet.col_values(4)[1])  # 結果為朋友
print(rsheet.col_values(4)[2])  # 這個是合並的行如果讀取就是空值
print(rsheet.row_values(6)[2])  # 結果為暫無
print(rsheet.row_values(6)[3])  # 這個是合並的列如果讀取就是空值
print(rsheet.merged_cells)
# 結果為[(6, 7, 2, 5), (1, 3, 4, 5), (3, 6, 4, 5)]
# 上面的的(6, 7, 2, 5)這個元組里面的元素分別為(row,row_range,col,col_range)
# (row,row_range)表示為包含row但是不包含row_range。上面可以解讀為
# 因為是從零開始計數的所以可以這樣說第七行(數字為6)的第三列(數字為2)到第五列(數字為4)合並


# 有上面的規律我們可以使用以下方式獲取合並單元格的內容
# 這樣我們就可以使用以下的方式獲取合並的單元格的信息,
merge = []
for (rlow, rhigh, clow, chigh) in rsheet.merged_cells:
    merge.append([rlow, clow])
for index in merge:
    print(rsheet.cell_value(index[0], index[1]))

# 有上面我們知道列合並我們可以看到該行的合並的第一列的內容就是合並列的內容其他的就不是這個內容。
# 為了准確的獲得合並單元格的內容我們可以使用上面的方式獲得

寫excel-->xltw

#!/usr/bin/env python
# -*-coding:utf-8-*-
import xlwt, xlrd

f = xlwt.Workbook()  # 創建一個工作簿
sheet1 = f.add_sheet('sheet1', cell_overwrite_ok=True)  # 創建sheet
row0 = ["姓名", "年齡", "出生日期", "愛好"]
column0 = ["張三", "李四", "王五"]
# 生成第一行
for i in range(0, len(row0)):
    sheet1.write(0, i, row0[i])  # 第一個參數表示的是行,第二個參數表示的列,第三個表示的是數據

for i in range(0, len(column0)):
    sheet1.write(i + 1, 0, column0[i])
# 給第二行的人物加信息
sheet1.write(1, 1, 23)
sheet1.write(1, 2, '1993/04/22')
sheet1.write(1, 3, '足球')
f.save('test.xls')

 

上面這個只是寫入一個新的不能夠對已有的Excel表格進行修改

OpenPyXL

由於xlrd不能對已存在的xlsx文件,進行修改!所以必須使用OpenPyXL

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模塊的安裝

 pip3 install OpenPyXL

2、快速實現xlsx文件的單元格修改

舉例:增加一列地區,並增加相應的值,並且修改某一個人的出生日期

from openpyxl import load_workbook

# excel文件絕對路徑
file_home = r'C:\Users\PC\Desktop\sss.xlsx'

wb = load_workbook(filename=file_home)  # 打開excel文件
sheet_ranges = wb['Sheet1']
print(sheet_ranges['A1'].value)  # 打印A1單元格的值
ws = wb['Sheet1']  # 根據Sheet1這個sheet名字來獲取該sheet
# 添加一欄為地區,並且給上數據
ws["F1"] = '地區'  # 修改C1的值為LJK5679842
ws['F2'] = '湖北'
ws['F3'] = '雲南'
ws['F4'] = '湖南'
ws['F5'] = '北京'
ws['F6'] = '江蘇'

# 修改小明的出生日期
ws['c3'] = '1991/11/12'
wb.save(file_home)  # 保存修改后的excel

 

執行前的excel表格

執行后的Excel表格

 

可以看到上面增加和修改的數據。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM