python讀寫excel利器:xlwings 從入門到精通



xlwings簡介:
python操作Excel的模塊,網上提到的模塊大致有:xlwings、xlrd、xlwt、openpyxl等,
他們提供的功能歸納起來有兩種:

一、用python讀寫Excel文件,實際上就是讀寫有格式的文本文件,操作excel文件和操作text、csv文件沒有區別,Excel文件只是用來儲存數據。
二、除了操作數據,還可以調整Excel文件的表格寬度、字體顏色等。

xlwings和目前流行的其它xlsxwriter, openpyxl的區別:

特點:

  • xlwings能夠非常方便的讀寫Excel文件中的數據,並且能夠進行單元格格式的修改
  • 可以和matplotlib以及pandas無縫連接
  • 可以調用Excel文件中VBA寫好的程序,也可以讓VBA調用用Python寫的程序。
  • 開源免費,一直在更新

安裝和使用

pip install xlwings
conda install xlwings
conda install -c conda-forge xlwings

xlwings中文文檔
https://www.kancloud.cn/gnefnuy/xlwings-docs/1127450

英文文檔:
https://docs.xlwings.org/en/stable/quickstart.html

excel基本結構分為 Application ——> Workbooks ——> Worksheets ——> Range.
即應用程序 ——> 工作簿 ——> 工作表 ——> 單元格。

在xlwings中

  • Excel程序用App來表示,多個Excel程序集合用Apps表示;
  • 單個工作簿用Book表示,工作簿集合用Books表示;
  • 單個工作表用Sheet表示,工作表集合用Sheets表示;
  • 區域用Range表示,既可以是一個單元格,也可以是一片單元格區域。

明確幾個概念:

  1. 新建:創建一個不存在的工作薄或者工作表
  2. 打開:打開一個已經存在的工作薄
  3. 引用:就是告訴程序,你要操作哪個對象。比如你打開了A、B、C三個工作薄,現在你想操作B工作薄,就要先引用B
  4. 激活:我們可以同時打開多個工作薄,但是一次只能操作一個工作簿,我們正在操作的這個工作薄稱為當前活動工作薄,激活的意思就是將某一個對象(工作薄或工作表等)變成當前活動對象

基礎操作

import xlwings as xw

app = xw.App(visible=True, add_book=False)
app.display_alerts = False    # 關閉一些提示信息,可以加快運行速度。 默認為 True。
app.screen_updating = True    # 更新顯示工作表的內容。默認為 True。關閉它也可以提升運行速度。
wb = app.books.add()
sht = wb.sheets.active

操作工作簿

# wb = app.books.add()                   # 新建工作簿。
# wb = app.books.open(r'file_path')      # 打開現有的工作簿
# wb = app.books.active                  # 獲取當前活動的工作簿

操作工作表

sht = wb.sheets.active                 # 獲取當前活動的工作表
sht = wb.sheets[0]                     # 按索引獲取工作表
sht = wb.sheets['Sheet1']              # 按表名獲取工作表
sht1 = wb.sheets.add()                 # 新建工作表,默認新建的放在最前面。
sht1 = wb.sheets.add('新建工作表', after=sht)   # 新建工作表,放在sht工作表后面。

讀取單元格

cell1 = sht.range('cell1')
# 獲取 cell1 中的值
v = cell1.value
# 也可以根據行列號讀取
cell1_value = sht.range(3,2).value
# 讀取一段區間內的值
a1_c4_value = sht.range('a1:c4').options(ndim=2).value       # 加上 option 讀取二維的數據
a1_c4_value = sht.range((1,1),(4,3)).options(ndim=2).value   # 和上面讀取的內容一樣。

寫入(單元格賦值)

sht.range(3,2).value = 'welcome'
sht.range('A1').value=[1,2,3]
# 將A1,B1,C1單元格的值存入list1列表中
list1=sht.range('A1:C1').value
# 將1,2,3分別寫入了A1,A2,A3單元格中
sht.range('A1').options(transpose=True).value=[1,2,3]
# 將A1,A2,A3單元格中值存入list1列表中
list1=sht.range('A1:A3').value

前面操作的是單個單元格,接下來我們來操作一行或一列

sheet.range('A1').value = [1, 2, 3, 4, 5]  #向 A1:E1 寫入數據print(sheet.range('A1:E1').value)   

xlwings 還提供了另外一種更加方便的方式來操作一個區域塊,通過 expand 或 options 中的 expand 參數,expand 使用的是當前已獲取的區域對象,而 options 中的 expand 參數在調用時才計算區域對象,推薦使用 options 中的 expand 參數,是你可以在更改區域后及時獲取區域的變化。下面的代碼,可以清楚的表達兩種方式的不同。

sheet.range('A1').value = [[1,2], [3,4]]
rng1 = sheet.range('A1').expand('table')
rng2 = sheet.range('A1').options(expand='table')
print(rng1.value)
# [[1.0, 2.0], [3.0, 4.0]]
print(rng2.value)
# [[1.0, 2.0], [3.0, 4.0]]
sheet.range('A3').value = [5, 6]
print(rng1.value)
# [[1.0, 2.0], [3.0, 4.0]]
print(rng2.value)
# [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]

舉例(二維數據寫入):

# 將a1,a2,a3輸入第一列,b1,b2,b3輸入第二列
list1=[[‘a1’,'a2','a3'],['b1','b2','b3']]
sht.range('A1').value=list1

# 將A1:B3的值賦給二維列表list1
list1=sht.range('A1:B3').value

Excel中區域的選取表格(按行或按列選取)

# 選取第一列
rng=sht. range('A1').expand('down')
rng.value=['a1','a2','a3']
# 選取第一行
rng=sht.range('A1').expand('right')
#rng=['a1','b1']

# 選取表格
rng.sht.range('A1').expand('table')
rng.value=[['a1','a2','a3'],['b1','b2','b3']]

range的操作(range常用的api)

# 引用當前活動工作表的單元格
rng=xw.Range('A1')
# 加入超鏈接
# rng.add_hyperlink(r'www.baidu.com','百度',‘提示:點擊即鏈接到百度')
# 取得當前range的地址
rng.address
rng.get_address()
# 清除range的內容
rng.clear_contents()
# 清除格式和內容
rng.clear()
# 取得range的背景色,以元組形式返回RGB值
rng.color
# 設置range的顏色
rng.color=(255,255,255)
# 清除range的背景色
rng.color=None
# 獲得range的第一列列標
rng.column
# 返回range中單元格的數據
rng.count
# 返回current_region
rng.current_region
# 返回ctrl + 方向
rng.end('down')
# 獲取公式或者輸入公式
rng.formula='=SUM(B1:B5)'
# 數組公式
rng.formula_array
# 獲得單元格的絕對地址
rng.get_address(row_absolute=True, column_absolute=True,include_sheetname=False, external=False)
# 獲得列寬
rng.column_width
# 返回range的總寬度
rng.width
# 獲得range的超鏈接
rng.hyperlink
# 獲得range中右下角最后一個單元格
rng.last_cell
# range平移
rng.offset(row_offset=0,column_offset=0)
#range進行resize改變range的大小
rng.resize(row_size=None,column_size=None)
# range的第一行行標
rng.row
# 行的高度,所有行一樣高返回行高,不一樣返回None
rng.row_height
# 返回range的總高度
rng.height
# 返回range的行數和列數
rng.shape
# 返回range所在的sheet
rng.sheet
#返回range的所有行
rng.rows
# range的第一行
rng.rows[0]
# range的總行數
rng.rows.count
# 返回range的所有列
rng.columns
# 返回range的第一列
rng.columns[0]
# 返回range的列數
rng.columns.count
# 所有range的大小自適應
rng.autofit()
# 所有列寬度自適應
rng.columns.autofit()
# 所有行寬度自適應
rng.rows.autofit()
寫入一行或一列Excel數據(函數式)

注意點:這里的sheet參數必須是已經存在的sheet表,不能新建

import xlwings as xw
def write_col(io, sheet, col='A1', data=None):
    """
    寫入一列數據
    :param io: Excel文件
    :param sheet: sheet,int或者str類型
    :param col: 哪一列,如:'A1'
    :param data: 要寫入的數據,list類型
    :return:
    """
    wb = xw.Book(io)
    if isinstance(sheet, str):
        sht = wb.sheets(sheet)
    else:
        sht = wb.sheets[sheet]
    sht.range(col).options(transpose=True).value = data
    wb.save()
    wb.app.quit()
一次寫多列
注意點:此方法所需的data參數必須是list嵌套,如:[[1, 9], [2, 8], [3, 7], [4, 6]],並且里面的每個list的長度必須一致

def write_col(io, sheet, col='A1', data=None):
    """
    寫入多列數據
    :param io: Excel文件
    :param sheet: sheet,int或者str類型
    :param row: 從哪一列開始寫入,如:'A1'
    :param data: 要寫入的數據,嵌套list類型
    :return:
    """
    wb = xw.Book(io)
    if isinstance(sheet, str):
        sht = wb.sheets(sheet)
    else:
        sht = wb.sheets[sheet]
    sht.range(col).value = data
    wb.save()
    wb.app.quit()

寫入效果如下:

寫入行,一次寫一行
注意點:此方法所需的data參數是list類型,如:[1, 2, 3, 4]

def write_row(io, sheet, row='A1', data=None):
    """
    寫入一行數據
    :param io: Excel文件
    :param sheet: sheet,int或者str類型
    :param row: 哪一行,如:'A1'
    :param data: 要寫入的數據,list類型
    :return:
    """
    wb = xw.Book(io)
    if isinstance(sheet, str):
        sht = wb.sheets(sheet)
    else:
        sht = wb.sheets[sheet]
    sht.range(row).value = data
    wb.save()
    wb.app.quit()
一次寫多行
注意點:此方法所需的data參數必須是list嵌套,如:[[1, 2], [3, 4], [5, 6]],並且里面的每個list的長度必須一致

def write_row(io, sheet, row='A1', data=None):
    """
    寫入多行數據
    :param io: Excel文件
    :param sheet: sheet,int或者str類型
    :param col: 從哪一行開始寫入,如:'A1'
    :param data: 要寫入的數據,嵌套list類型
    :return:
    """
    wb = xw.Book(io)
    if isinstance(sheet, str):
        sht = wb.sheets(sheet)
    else:
        sht = wb.sheets[sheet]
    sht.range(row).options(transpose=True).value = data
    wb.save()
    wb.app.quit()
寫入效果如下:

使用range('A1').api.AddComment('comments')給單元格加注釋
ws1 = wb.sheets.add('原始整理')
ws1.range('A1').value = 'name_list_bank'
ws1.range('A1').api.AddComment('該表是匯總大家的待授信銀行機構名單')
ws1.range('A2').options(transpose=True).value = sorted(name_list_bank)
ws1.range('B1').value = 'name_none_bank'
ws1.range('B1').api.AddComment('該表是匯總數人的待授信非銀行機構名單')
ws1.range('B2').options(transpose=True).value =  sorted(name_none_bank)

格式設置

使用xlwings模塊進行excel表格操作時,難免會用到對單元格進行格式設置,比如常用到的對單元格設置為文本格式、日期時間格式、小數和百分數,下面列出常用:
使用range().api.NumberFormat = XXX即可修改格式

比如:

range('A1').api.NumberFormat = "@"  #設置為文本格式
range('A2').api.NumberFormat = "0.0"  #設置為小數格式
range('A3').api.NumberFormat = "yyyy-mm-dd"  #設置為"-"連接的日期格式
range('A4').api.NumberFormat = "0%"  #設置為百分比

設置單元格大小

sht.autofit()    # 自動調整單元格大小。注:此方法是在單元格寫入內容后,再使用,才有效。
sht.range(1,4).column_width = 5    # 設置第4列 列寬。(1,4)為第1行第4列的單元格
sht.range(1,4).row_height = 20     # 設置第1行 行高

設置單元格 字體格式

cell1.color = 255,200,255         # 設置單元格的填充顏色
cell1.api.Font.ColorIndex = 3     # 設置字體的顏色,具體顏色索引見下方。
cell1.api.Font.Size = 24          # 設置字體的大小。
cell1.api.Font.Bold = True        # 設置為粗體。
cell1.api.HorizontalAlignment = -4108    # -4108 水平居中。 -4131 靠左,-4152 靠右。
cell1.api.VerticalAlignment = -4130      # -4108 垂直居中(默認)。 -4160 靠上,-4107 靠下, -4130 自動換行對齊。
cell1.api.NumberFormat = "0.00"          # 設置單元格的數字格式。

設置邊框

# Borders(9) 底部邊框,LineStyle = 1 直線。
cell1.api.Borders(9).LineStyle = 1
cell1.api.Borders(9).Weight = 3                # 設置邊框粗細。

# Borders(7) 左邊框,LineStyle = 2 虛線。
cell1.api.Borders(7).LineStyle = 2
cell1.api.Borders(7).Weight = 3

# Borders(8) 頂部框,LineStyle = 5 雙點划線。
cell1.api.Borders(8).LineStyle = 5
cell1.api.Borders(8).Weight = 3

# Borders(10) 右邊框,LineStyle = 4 點划線。
cell1.api.Borders(10).LineStyle = 4
cell1.api.Borders(10).Weight = 3

# Borders(5) 單元格內從左上角 到 右下角。
cell1.api.Borders(5).LineStyle = 1
cell1.api.Borders(5).Weight = 3

# Borders(6) 單元格內從左下角 到 右上角。
cell1.api.Borders(6).LineStyle = 1
cell1.api.Borders(6).Weight = 3

如果是一個區域的單元格,內部邊框設置如下

# # Borders(11) 內部垂直邊線。
# cell1.api.Borders(11).LineStyle = 1
# cell1.api.Borders(11).Weight = 3
# 
# # Borders(12) 內部水平邊線。
# cell1.api.Borders(12).LineStyle = 1
# cell1.api.Borders(12).Weight = 3

單元格操作

合並拆分單元格

sht.range('C8:D8').api.merge()      # 合並單元格 C8 到 D8
sht.range('C8:D8').api.unmerge()    # 拆分單元格。

插入 、刪除 一行

sht1.range('a3').api.EntireRow.Delete()     # 會刪除 ’a3‘ 單元格所在的行。
sht1.api.Rows(3).Insert()                   # 會在第3行插入一行,原來的第3行下移。

插入 、刪除 一列

sht1.range('c2').api.EntireColumn.Delete()  # 會刪除 ’c2‘ 單元格所在的列。
sht1.api.Columns(3).Insert()                # 會在第3列插入一列,原來的第3列右移。(也可以用列的字母表示)

選擇sheet頁面最右下角的單元格,獲取最大行數,和列數

# 區別 expand(), expand()只選中與之連續的單元格。
cell = sht1.used_range.last_cell
rows = cell.row
columns = cell.column

# cell = sht1.range("a1").expand("down")
# max_rows = cell.rows.count              # 獲取最大行數

排序,刪除重復值

排序使用方法:
1、選擇需要排序的區域。這里用 'a2' 是因為排序的數據送從第二行開始的,第一行是標題,不應該參與排序。
2、選擇按那一列進行排序 Key1=sht.range('c2').api, 這里選擇的是按 第 C 列排序,所以這里選擇 c1 和 c2 都可以。
3、Order1=1 為升序,2為降序。

sht1.range('a2',(rows,columns)).api.Sort(Key1=sht.range('c2').api, Order1=1)

刪除重復值使用方法:

# RemoveDuplicates(3) 為按第3列內容進行刪除重復項。
sht1.range('a2',(rows,columns)).api.RemoveDuplicates(3)

插入、讀取公式

sht1.range('d1').formula = '=sum(e1+f1)'    # 插入公式
print(sht1.range('d1').formula)

同個表格復制、粘貼

# 復制 a2 到 a6 之間單元格的值,粘貼到'a15'中
sht.range('a2','a6').api.Copy(sht.range('a15').api)

跨表格復制、粘貼

my_values = sht_1.range('a2:d4').options(ndim=2).value    # 讀取二維的數據
sht_2.range('a1').value = my_values

關閉文件

wb.save()
#wb.close()
#app.quit()

其它功能

清除單元格內容和格式 sheet.range('A1').clear()
單元格的列標 sheet.range('A1').column
單元格的行標 sheet.range('A1').row
單元格的行高 sheet.range('A1').row_height
單元格的列寬 sheet.range('A1').column_width
列寬自適應 sheet.range('A1').columns.autofit()
行高自適應 sheet.range('A1').rows.autofit()
單元格背景色(RGB) sheet.range('A1').color=(34,139,34)
清除單元格顏色 sheet.range('A1').color=None
輸入公式,相應單元格會出現計算結果 sheet.range('A1').formula='=SUM(A1:E1)
獲取單元格公式 sheet.range('A1').formula_array

踩過的坑

解決xlwings寫入長數字型字符串時變成科學計數法的問題

解決要點:要先把要設置的那一列,設置為文本格式,再給那個區域賦值(次序倒過來是不行的)

sht = wb.sheets.add('買入清單')
sht.range('B:B').api.NumberFormat ="@"
sht.range('A1').value = df_gz_buy
sht.autofit('c')

#或者寫成:
sht2 = wb.sheets.add('賣出清單',after =sht)
range2 = sht2.range('B:B')
range2.api.NumberFormat ="@"
sht2.range('A1').value = df_gz_sell
sht2.autofit('c')

參考資料:

官網:https://docs.xlwings.org/en/stable/
官網中文:https://docs.xlwings.org/zh_CN/latest/quickstart.html
國外視頻教程(USD99)https://training.xlwings.org/p/xlwings
利用xlwings庫對excel進行字體(font)、邊框(border)、合並單元格(merge)等格式設置:http://www.dszhp.com/xlwings-format.html
不一樣的xlwings用法:https://blog.csdn.net/lly1122334/article/details/99706504
10秒搞定Xlwings全套操作:https://zhuanlan.zhihu.com/p/237583143
Python操作Excel的Xlwings教程(1-5)(強烈推薦):
https://blog.csdn.net/th1522856954/article/details/107850947
https://blog.csdn.net/th1522856954/article/details/107923265
https://blog.csdn.net/th1522856954/article/details/108111058
https://blog.csdn.net/th1522856954/article/details/108269219


免責聲明!

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



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