python讀、寫、修改、追寫excel文件(xlrd / xlwt / xlutils / openpyxl)


四個工具包

  python 操作 excel 的 4 個工具包如下

  • xlrd: 對 .xls 進行讀相關操作
  • xlwt: 對 .xls 進行寫相關操作
  • xlutils: 對 .xls 讀寫操作的整合
  • openpyxl:對 .xlsx 進行讀寫操作

注意,前三個庫都只能操作 .xls,不能操作 .xlsx。最后一個只能操作 .xlsx,不能操作 .xls

pip install xlrd
pip install xlwt
pip install xlutils
pip install openpyxl

 

xlwt 寫 .xls 文件

基本用法

import xlwt

wbk = xlwt.Workbook(encoding="utf-8") # 創建 xls 文件,可被復寫
datasheet = wbk.add_sheet("sheet1") # 創建一個名為sheet1的sheet

# 設置單元格的樣式,如字體、背景顏色等等
style = xlwt.easyxf('pattern: pattern solid, fore_colour red')

# 語法:write(n, m, "aaa", [style])===>第n行,第m列,內容, [樣式](樣式可以不指定,不指定即為默認樣式)
datasheet.write(0, 0, "十年之前", style)
datasheet.write(0, 1, "我不認識你")
datasheet.write(1, 2, "你不屬於我")
datasheet.write(2, 3, "我們還是一樣")

# 合並單元格
worksheet.write_merge(3, 4, 0, 3, '賠在一個陌生人左右') 
# 四個參數a,b,c,d:合並第 a 行到第 b 行,第 c 列到第 d 列

wbk.save("ttt.xls") # 保存

 

設置樣式

wk = xlwt.Workbook()    # 新建一個 Excel
sheet = wk.add_sheet('sheet1')    # 新建一個名為 sheer1 的工作簿

# 創建一個樣式對象,初始化樣式
style = xlwt.XFStyle()  
al = xlwt.Alignment()
al.horz = 0x02      # 設置水平居中0x02,左端對齊0x01,右端對齊0x03
al.vert = 0x01      # 設置垂直居中 0x01,上端對齊0x00,底端對齊0x02
style.alignment = al

sheet.write(0, 0, '文本居中', style)
wk.save('Test.xls')
設置文本對齊樣式(方式一)
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('sheet1')

# 文本對齊的對象
alignment = xlwt.Alignment()
# 水平方向的對齊樣式
alignment.horz = xlwt.Alignment.HORZ_CENTER # May be: HORZ_GENERAL, HORZ_LEFT, HORZ_CENTER, HORZ_RIGHT, HORZ_FILLED, HORZ_JUSTIFIED, HORZ_CENTER_ACROSS_SEL, HORZ_DISTRIBUTED
# 垂直方向的對齊樣式
alignment.vert = xlwt.Alignment.VERT_CENTER # May be: VERT_TOP, VERT_CENTER, VERT_BOTTOM, VERT_JUSTIFIED, VERT_DISTRIBUTED

# 初始化一個樣式對象,將對齊的對象作為他的一個屬性
style = xlwt.XFStyle() # Create Style
style.alignment = alignment # Add Alignment to Style
worksheet.write(0, 0, '冷咖啡離開了杯墊,我忍住的情緒在很后面', style)
workbook.save('Excel_Workbook.xls')
設置文本對齊樣式(方式二)
import xlwt

workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('sheet1')

style = xlwt.XFStyle() # 初始化樣式
font = xlwt.Font() # 為樣式創建字體
font.name = 'Times New Roman' # 字體名
font.bold = True # 加粗
font.underline = True # 下划線
font.italic = True # 斜體字
style.font = font # 設定樣式

worksheet.write(0, 0, 'Unformatted value') # 不帶樣式的寫入
worksheet.write(1, 0, 'Formatted value', style) # 帶樣式的寫入,多了一個 style 參數

workbook.save('ttt.xls') # 保存文件
設置文本的字體
import xlwt

workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('sheet1')
worksheet.write(0, 0,'你要的全拿走,把回憶化成空。留下我們的狗,不管有沒有用,我怕他以后沒人寵。')

# 設置單元格寬度
worksheet.col(0).width = 3333
workbook.save('cell_width.xls')
設置單元格寬度
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('sheet1')

worksheet.write(0, 0, xlwt.Formula('HYPERLINK("http://www.google.com";"Google")')) # 前面是鏈接,后面是文本
workbook.save('Excel_Workbook.xls')
添加超鏈接
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('sheet1')

# 邊框對象
borders = xlwt.Borders() 
# 設置邊框樣式,常用:DASHED虛線,THIN實線,NO_LINE沒有線
borders.left = xlwt.Borders.DASHED 
borders.right = xlwt.Borders.DASHED
borders.top = xlwt.Borders.DASHED
borders.bottom = xlwt.Borders.DASHED

# 所有邊框樣式: NO_LINE, THIN, MEDIUM, DASHED, DOTTED, THICK, DOUBLE, HAIR, MEDIUM_DASHED, THIN_DASH_DOTTED, MEDIUM_DASH_DOTTED, THIN_DASH_DOT_DOTTED, MEDIUM_DASH_DOT_DOTTED, SLANTED_MEDIUM_DASH_DOTTED, or 0x00 through 0x0D.

# 邊框顏色
borders.left_colour = 0x40
borders.right_colour = 0x40
borders.top_colour = 0x40
borders.bottom_colour = 0x40

# 初始化一個樣式對象,將邊框對象作為他的一個屬性
style = xlwt.XFStyle() # Create Style
style.borders = borders # Add Borders to Style

worksheet.write(0, 0, '幽默是世界上最好的禮物', style)
workbook.save('ttt.xls')
添加邊框
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('sheet1')

# Pattern對象用於聲明顏色
pattern = xlwt.Pattern()
pattern.pattern = xlwt.Pattern.SOLID_PATTERN # May be: NO_PATTERN, SOLID_PATTERN, or 0x00 through 0x12
pattern.pattern_fore_colour = 5 # 背景色(5是黃色)

# 創建樣式對象,顏色對象為他的屬性
style = xlwt.XFStyle() # Create the Pattern
style.pattern = pattern # Add Pattern to Style

worksheet.write(0, 0, '我頭戴圓頂禮帽鞋子特大號', style)
workbook.save('ttt.xls')

'''
其他常用背景色
0 = Black
1 = White
2 = Red,
3 = Green
4 = Blue
5 = Yellow
6 = Magenta
7 = Cyan
16 = Maroon
17 = Dark Green
18 = Dark Blue
19 = Dark Yellow , almost brown)
20 = Dark Magenta
21 = Teal
22 = Light Gray
23 = Dark Gray
......
'''
設置背景色顏色

 

xlrd 讀 .xls 文件

基本用法

import xlrd

data = xlrd.open_workbook('excelFile.xls') # 打開Excel文件讀取數據

# 獲取sheet
the_sheet = data.sheets()[0]              # 通過索引順序獲取(0是第一個sheet) 
the_sheet = data.sheet_by_index(0)        # 通過索引順序獲取,同上 
the_sheet = data.sheet_by_name(u'Sheet1') # 通過名稱獲取

# 獲取數據,返回值為list
data_list.row_values(1) # 第二行數據(支持負索引取值)
data_list.col_values(1) # 第二列數據

# 獲得行數和列數。
rows = the_sheet.nrows # 行數
cols = the_sheet.ncols # 列數
# 輸出每一行數據
for i in range(rows):
    print(the_sheet.row_values(i))

# 獲得指定單元格數據的三種方式
data = the_sheet.cell(0,0).value # 第一行第一列的值
data = the_sheet.row(0)[0].value # 第一行第一列
data = the_sheet.col(0)[0].value # 第一列第一行

data = the_sheet.cell(0,0).xf_index # 第一行第一列的背景色
data = the_sheet.row(0)[0].xf_index # 第一行第一列的背景色
data = the_sheet.col(0)[0].xf_index # 第一列第一行的背景色

 

修改excel

row=0 # 修改第一行
col=0 # 修改第一列

# ctype: 0-->empty,1-->string,2-->number,3-->date,4-->boolean,5-->error
cell_type=1 # 修改類型
value='你說你不懂我為何在這時牽手' # 修改內容

cell_A1=the_sheet.cell(0,0).value # 獲取第一行第一列的值

format=0

the_sheet.put_cell(row, col, cell_type, value, format) # 修改操作

cell_A1=the_sheet.cell(0,0).value # 再看一下,值已被改

 

其他

import xlrd
from flask import Flask, jsonify, request

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False

@app.route('/ttt', methods=['POST'])
def ttt():
    filestorage = request.files.get('upload')
    print(filestorage)
    f = filestorage.read()
    workbook = xlrd.open_workbook(file_contents=f)
    sheet2 = workbook.sheet_by_index(0)
    rows = sheet2.nrows  # 行數
    cols = sheet2.ncols  # 列數
    print(rows, cols)

    for i in range(rows):
        print(sheet2.row_values(i))

    return 'ttt'

if __name__ == '__main__':
    app.run( host='0.0.0.0')
在flask中,不經過磁盤IO直接讀取前端傳的.xls文件

 

xlutils 追寫 Excel

  xlwt 只能創建一個全新的 Excel 文件,然后對這個文件進行寫入內容以及保存。

  但是大多數情況下需求會是讀入一個 Excel 文件,然后進行修改或追加,這個時候,就決定用你了—— xlutils 。

下面的 demo 是給一個 Excel 文件追加內容:

from xlrd import open_workbook
from xlutils.copy import copy

# 用 xlrd 提供的方法讀取一個excel文件
rexcel = open_workbook("ttt.xls",formatting_info=True) # 保留原有樣式
# 用 xlrd 提供的方法獲得現在已有的行數
rows = rexcel.sheets()[0].nrows 
# 用 xlutils 提供的copy方法將 xlrd 的對象轉化為 xlwt 的對象
excel = copy(rexcel) 
# 用 xlwt 對象的方法獲得要操作的 sheet
table = excel.get_sheet(0) 
values = ["1", "2", "3"]
row = rows
for value in values:
    table.write(row, 0, value) # xlwt對象的寫方法,參數分別是行、列、值
    table.write(row, 1, "haha")
    table.write(row, 2, "lala")
    row += 1
excel.save("ttt.xls") # xlwt 對象的保存方法,這時便覆蓋掉了原來的 Excel

 

openpyxl 模塊

  openpyxl 模塊是一個讀寫 Excel 2010 文檔的 Python 庫,不支持更早格式的 Excel,openpyxl 模塊支持同時讀取和修改Excel文檔。

  openpyxl 模塊默認可讀可寫,若只需要讀或者寫的功能,可以在 open 時指定 write_only 或 read_only 為 True

  openpyxl 模塊中有三個不同層次的類,Workbook 是對工作簿的抽象,Worksheet 是對表格的抽象,Cell 是對單元格的抽象,每一個類都包含了許多屬性和方法。

注:openpyxl 只能操作 .xlsx,若需要插入圖片需要安裝 pillow 庫

 

打開 Excel 文件

  • 讀取已存在的 Excel 文件
  • 新建 Excel 工作簿
import openpyxl

# 打開已有的 .xlsx
data = openpyxl.load_workbook('xxx.xlsx') # 可讀可寫
data = openpyxl.load_workbook('xxx.xlsx', read_only=True) # 只讀
data = openpyxl.load_workbook('xxx.xlsx', write_only=True) # 只寫

# 創建一個新的 .xlsx
wb = openpyxl.Workbook()
# ...
wb.save('xxxxxxx.xlsx') # 保存

 

創建 sheet 並寫入值

  • 獲取sheet
  • 創建sheet
  • 刪除sheet
  • 復制sheet
  • 獲取sheet的屬性:標題、大小、最大行 / 列、最小行 / 列、數據
import openpyxl
import datetime
import time

wb = openpyxl.Workbook() #創建一個空的 Excel 工作簿

# ----------操作 sheet
ws = wb.active #獲取第一個sheet
ws1 = wb.create_sheet("sheet1") #創建一個名為sheet1的sheet
ws1.title = "New Title" #設定sheet的名字
ws1.sheet_properties.tabColor = "1072BA" #設定sheet標簽的背景顏色
ws2 = wb.create_sheet("sheet2", 0) #創建一個sheet並設定插入位置,默認插在后面
ws2.title = u"夜的第七章" #sheet的名字必須是Unicode

# ----------在指定單元格寫入值
ws['A1'] = 1980      #寫入數字
ws['B1'] = "你是我的"+"OK綳" #寫入中文(unicode中文也可)
ws.append([1, 2, 3])  #批量寫入多個單元格
ws['A2'] = datetime.datetime.now() #寫入一個當前時間
ws['A3'] =time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) #寫入一個自定義的時間格式

# ----------獲取全部sheet的名字,遍歷sheet名字
print(wb.sheetnames)
for sheet_name in wb.sheetnames:
    print(sheet_name)

for sheet in wb:
    print sheet.title

# ----------獲取指定sheet對象
print(wb.get_sheet_by_name(u"夜的第七章"  ))
print(wb["New Title" ])

# ----------復制一個sheet
w3 = wb.copy_worksheet(wb['new title'])
ws3.title = 'new2'

# ----------刪除一個sheet
wb.remove_sheet(wb['new title'])

# ----------sheet對象的各種屬性
print(ws.title) # 表格的標題
print(ws.dimensions) # 表格的大小,指含有數據的表格的大小,即:左上角的坐標:右下角的坐標
print(ws.max_row) # 表格的最大行
print(ws.min_row) #表格的最小行
print(ws.max_column) # 表格的最大列
print(ws.min_column) # 表格的最小列
print(ws.rows) # 按行獲取單元格(Cell對象) - 生成器
print(ws.columns) # 按列獲取單元格(Cell對象) - 生成器
print(ws.values) # 按行獲取表格的內容(數據) - 生成器

# 保存
wb.save("ttt.xlsx")
View Code

 

操作單元格

  • 獲取單元格屬性
  • 在指定單元格插入數據
  • 查看單元格類型
  • 使用公式
  • 合並、拆分單元格
  • 隱藏單元格
  • 操作多行、多列
import openpyxl

wb = Workbook()
ws1 = wb.create_sheet("sheet1")

# ----------獲取單元格指定屬性
print(ws1.cell(row=1,column=2).row) # 單元格所在的行
print(ws1.cell(row=1,column=2).column) # 單元格坐在的列
print(ws1.cell(row=1,column=2).value) # 單元格的值
print(ws1.cell(row=1,column=2).coordinate) # 單元格的坐標

# ----------在指定單元格插入數據
ws1["A1"] = '久未放晴的天空'
ws1["A2"] = '依舊留着你的笑容'
ws1["A3"] = '哭過卻又無法掩埋歉疚'
ws1["B1"] = 123
ws1["B2"] = 456
ws1["B3"] = 789
ws1["C2"] = time.strftime("%Y年%m月%d日 %H時%M分%S秒",time.localtime())
d = ws1.cell(row=4, column=3, value=10)

# ----------存入百分數
ws1["D1"]="12%" # 存入百分數,其實是小數
print(ws1["D1"].value) # 0.12
# 正確方法
wb.guess_types = False
ws1["D2"]="12%"
print(ws1["D2"].value) # 12%

# ----------查看單元格類型
print(ws1["A1"].number_format) # General
print(ws1["B1"].number_format) # General
print(ws1["C2"].number_format) # yyyy-mm-dd h:mm:ss
print(ws1["D1"].number_format) # 0.00_ 
print(ws1["D2"].number_format) # 0%
# 數字需要在Excel中設置數字類型guess_types=True,直接寫入的數字是常規類型

# ----------使用公式
ws1["B4"] = "=SUM(1, 1)"
ws1["B5"] = "=SUM(B1:B3)"
prit(ws1["B4"]) # 打印的是公式內容,不是公式計算后的值,程序無法取到計算后的值

# ----------合並單元格
ws.merge_cells('E2:J2')
ws.merge_cells(start_row=2,start_column=1,end_row=2,end_column=4)

# ----------拆分單元格
# 針對本來就合並的單元格,不能直接執行拆分,需要先執行合並再執行拆分
ws.unmerge_cells('E2:J2') 
ws.unmerge_cells(start_row=2,start_column=1,end_row=2,end_column=4)

# ----------隱藏單元格
ws1.column_dimensions.group('A', 'D', hidden=True)   #隱藏a到d列范圍內的列

# ----------獲取單列的值
print(ws1["A"]) # 元祖 
for cell in ws1["A"]:
    print(cell.value) 

# ----------操作多列,獲取每一個值
print(ws1["A:C"]) # 獲取A到C列,元祖套元祖
for column in ws1["A:C"]:
    for cell in column:
        print(cell.value)

for row in ws1.iter_rows(min_row=1, min_col=1, max_col=3, max_row=3):
    for cell in row:
        print(cell.value)

# ----------獲取所有行
prin(ws1.rows)
for row in ws1.rows:
    print(row)

# ----------獲取所有列
prin(ws1.columns)
for col in ws1.columns:
    print(col)

wb.save("ttt.xlsx")
View Code

 

獲取行對象、列對象

  • 獲取指定行 / 列的值
import openpyxl

wb = openpyxl.load_workbook('e:\\sample.xlsx')
ws = wb.active
rows = []
for row in ws.iter_rows():
    rows.append(row)

cols = []
for col in ws.iter_cols():
    cols.append(col)

# 行、列同理
print(rows) #所有行
print(rows[0]) #獲取第一行
print(rows[0][0]) #獲取第一行第一列的單元格對象
print(rows[0][0].value) #獲取第一行第一列的單元格對象的值
print(rows[-1] ) #獲取最后行 print rows[-1]
print(rows[len(rows)-1][len(rows[0])-1]) #獲取第后一行和最后一列的單元格對象
print(rows[len(rows)-1][len(rows[0])-1].value) #獲取第后一行和最后一列的單元格對象的值
View Code

 

設定指定區域表格的樣式

# -*- coding: utf-8 -*-
from openpyxl import load_workbook
from openpyxl import Workbook
from openpyxl.worksheet.table import Table, TableStyleInfo

wb = Workbook()
ws = wb.active

data = [
    ['Apples', 10000, 5000, 8000, 6000],
    ['Pears',   2000, 3000, 4000, 5000],
    ['Bananas', 6000, 6000, 6500, 6000],
    ['Oranges',  500,  300,  200,  700],
]

# 表頭,必須是string
ws.append(["Fruit", "2011", "2012", "2013", "2014"])
for row in data:
    ws.append(row)

tab = Table(displayName="Table1", ref="A1:E5")

# 是否隔行換色,是否隔列換色
style = TableStyleInfo(name="TableStyleMedium9", showFirstColumn=True,
                       showLastColumn=True, showRowStripes=True, showColumnStripes=True)

tab.tableStyleInfo = style
ws.add_table(tab)

wb.save("ttt.xlsx")
View Code

 

設定字體樣式

  • 設定字體
  • 設定對齊方式
  • 設定是否加鎖、是否隱藏
  • 設定行 / 列的字體
# -*- coding: utf-8 -*-
from openpyxl import Workbook
from openpyxl.styles import colors
from openpyxl.styles import Font
from copy import copy

wb = Workbook()
ws = wb.active

a1 = ws['A1']
d4 = ws['D4']

# ----------設定字體
ft = Font(color=colors.RED, # 設定顏色,也可以用顏色編碼如color="FFBB00"
          name=u'宋體', # 設定字體
          size=14, # 設定字體大小
          italic=True, # 傾斜字體
          bold=True, # 設定粗體
          underline="single" # 設定下划線
               ) 
a1.font = ft
d4.font = ft

# ----------設定對齊方式
alignment=Alignment(horizontal='general',
                    vertical='bottom',
                    text_rotation=0,
                    wrap_text=False,
                    shrink_to_fit=False,
                    indent=0)
a1.alignment = alignment
d4.alignment = alignment

# ----------設定加鎖或隱藏
protection = Protection(locked=True,
                        hidden=False)


# ----------設定行和列的字體
col = ws.column_dimensions['B']
col.font = ft
row = ws.row_dimensions[1]
row.font = Font(underline="single") #將第一行設定為下划線格式

wb.save("ttt.xlsx")
View Code

 

設定單元格樣式

  • 設定單元格背景色
  • 設定單元格邊框
# -*- coding: utf-8 -*-
from openpyxl import Workbook
from openpyxl.styles import Font
from openpyxl.styles import NamedStyle, Font, Border, Side,PatternFill, colors

wb = Workbook()
ws = wb.active

highlight = NamedStyle(name="highlight")
highlight.font = Font(bold=True, size=20,color= "ff0100")
highlight.fill = PatternFill("solid", fgColor="DDDDDD") # 背景色
bd = Side(style='thick',  # 'hair', 'medium', 'dashDot', 'dotted', 'mediumDashDot', 'dashed', 'mediumDashed', 'mediumDashDotDot', 'dashDotDot', 'slantDashDot', 'double', 'thick', 'thin'
          color="000000",
          )
highlight.border = Border(left=bd, top=bd, right=bd, bottom=bd)

print(dir(ws["A1"]))
ws["A1"].style =highlight

# 單獨設定單元格的背景色樣式
sht["A1"] = "故事的小黃花"
sht["A3"] = "從出生那年就飄着"
sht["A5"] = "童年的盪秋千"
sht["A7"] = "隨記憶一直搖到現在"

fill_1 = PatternFill("solid", fgColor="1874CD") # 藍色
fill_2 = PatternFill("solid", fgColor="BCEE68") # 綠色
fill_3 = PatternFill("solid", fgColor=colors.RED) # 紅色
fill_4 = PatternFill("lightVertical", fgColor=colors.GREEN) # 虛線背景色

sht["A1"].fill = fill_1
sht["A3"].fill = fill_2
sht["A5"].fill = fill_3
sht["A7"].fill = fill_4

wb.save("ttt.xlsx")
View Code

 

插入圖片

  需要先安裝Pilow

# -*- coding: utf-8 -*-
from openpyxl import load_workbook
from openpyxl.drawing.image import Image

wb = load_workbook('ttt.xlsx')
ws1 = wb.active

img = Image('ttt.png')
ws1.add_image(img, 'A1')

wb.save("ttt.xlsx")

 

插入餅圖

# -*- coding: utf-8 -*-
from openpyxl import load_workbook
from openpyxl import Workbook
from openpyxl.chart import (PieChart , ProjectedPieChart, Reference)
from openpyxl.chart.series import DataPoint

data = [
    ['Pie', 'Sold'],
    ['Apple', 50],
    ['Cherry', 30],
    ['Pumpkin', 10],
    ['Chocolate', 40],
]

wb = Workbook()
ws = wb.active

for row in data:
    ws.append(row)

pie = PieChart()
labels = Reference(ws, min_col=1, min_row=2, max_row=5)
data = Reference(ws, min_col=2, min_row=1, max_row=5)
pie.add_data(data, titles_from_data=True)
pie.set_categories(labels)
pie.title = "Pies sold by category"

# Cut the first slice out of the pie
slice = DataPoint(idx=0, explosion=20)
pie.series[0].data_points = [slice]

ws.add_chart(pie, "D1")

ws = wb.create_sheet(title="Projection")

data = [
    ['Page', 'Views'],
    ['Search', 95],
    ['Products', 4],
    ['Offers', 0.5],
    ['Sales', 0.5],
]

for row in data:
    ws.append(row)

projected_pie = ProjectedPieChart()
projected_pie.type = "pie"
projected_pie.splitType = "val" # split by value
labels = Reference(ws, min_col=1, min_row=2, max_row=5)
data = Reference(ws, min_col=2, min_row=1, max_row=5)
projected_pie.add_data(data, titles_from_data=True)
projected_pie.set_categories(labels)

ws.add_chart(projected_pie, "A10")

from copy import deepcopy
projected_bar = deepcopy(projected_pie)
projected_bar.type = "bar"
projected_bar.splitType = 'pos' # split by position

ws.add_chart(projected_bar, "A27")

# Save the file
wb.save("ttt.xlsx")

 

 

 

 

 參考:https://www.cnblogs.com/zeke-python-road/p/8986318.html

 

 

       

                


免責聲明!

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



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