python-excel自动化-openpyxl

openpyxl学习笔记

创建或打开表格

python 复制代码
# 创建
import datetime 
from  openpyxl import  Workbook 
# 实例化
wb = Workbook()
# 激活 worksheet
ws = wb.active

# 打开已有
# from openpyxl  import load_workbook
# wb2 = load_workbook('文件名称.xlsx')

存储和遍历数据

python 复制代码
# 存储数据
# 方式一:数据可以直接分配到单元格中(可以输入公式)
ws['A1'] = 42
# 方式二:可以附加行,从第一列开始附加(从最下方空白处,最左开始)(可以输入多行)
ws.append([1, 2, 3])
# 方式三:Python 类型会被自动转换
ws['A3'] = datetime.datetime.now().strftime("%Y-%m-%d")

# 创建表
ws1 = wb.create_sheet("Mysheet1")
ws2 = wb.create_sheet("Mysheet2", 0)
# 选择表
# sheet 名称可以作为 key 进行索引
ws3 = wb["Mysheet1"]
ws4 = wb.get_sheet_by_name("Mysheet1")
wb.remove_sheet(ws4)# 删除指定sheet
ws3 is ws4

# 显示所有表名
print(wb.sheetnames)

# 遍历所有表
for sheet in  wb:
    print(sheet.title)
    
    
    
# 访问单元格(call)
# 1.单一单元格访问
# 方法一
c = ws['A4']
# 方法二:row 行;column 列
d = ws.cell(row=4, column=2, value=10)
# 方法三:只要访问就创建
for i in  range(1,101):
         for j in range(1,101):
            ws.cell(row=i, column=j)
            
# 2.多单元格访问
# 通过切片
cell_range = ws['A1':'C2']
# 通过行(列)
colC = ws['C']
col_range = ws['C:D']
row10 = ws[10]
row_range = ws[5:10]
# 通过指定范围(行 → 行) 遍历行
for row in  ws.iter_rows(min_row=1, max_col=3, max_row=2):
    for cell in  row:
        print(cell)

# 通过指定范围(列 → 列) 遍历列
for row in  ws.iter_cols(min_row=1, max_col=3, max_row=2):
    for cell in  row:
        print(cell)

# 遍历所有 方法一
ws = wb.active
ws['C9'] = 'hello world'
tuple(ws.rows)

# ((<Cell 'Mysheet2'.A1>, <Cell 'Mysheet2'.B1>, <Cell 'Mysheet2'.C1>),
#  (<Cell 'Mysheet2'.A2>, <Cell 'Mysheet2'.B2>, <Cell 'Mysheet2'.C2>),
#  (<Cell 'Mysheet2'.A3>, <Cell 'Mysheet2'.B3>, <Cell 'Mysheet2'.C3>),
#  (<Cell 'Mysheet2'.A4>, <Cell 'Mysheet2'.B4>, <Cell 'Mysheet2'.C4>),
#  (<Cell 'Mysheet2'.A5>, <Cell 'Mysheet2'.B5>, <Cell 'Mysheet2'.C5>),
#  (<Cell 'Mysheet2'.A6>, <Cell 'Mysheet2'.B6>, <Cell 'Mysheet2'.C6>),
#  (<Cell 'Mysheet2'.A7>, <Cell 'Mysheet2'.B7>, <Cell 'Mysheet2'.C7>),
#  (<Cell 'Mysheet2'.A8>, <Cell 'Mysheet2'.B8>, <Cell 'Mysheet2'.C8>),
#  (<Cell 'Mysheet2'.A9>, <Cell 'Mysheet2'.B9>, <Cell 'Mysheet2'.C9>))

# 遍历所有 方法二
tuple(ws.columns)

# ((<Cell 'Mysheet2'.A1>,
#   <Cell 'Mysheet2'.A2>,
#   <Cell 'Mysheet2'.A3>,
#   <Cell 'Mysheet2'.A4>,
#   <Cell 'Mysheet2'.A5>,
#   <Cell 'Mysheet2'.A6>,
#   <Cell 'Mysheet2'.A7>,
#   <Cell 'Mysheet2'.A8>,
#   <Cell 'Mysheet2'.A9>),
#  (<Cell 'Mysheet2'.B1>,
#   <Cell 'Mysheet2'.B2>,
#   <Cell 'Mysheet2'.B3>,
#   <Cell 'Mysheet2'.B4>,
#   <Cell 'Mysheet2'.B5>,
#   <Cell 'Mysheet2'.B6>,
#   <Cell 'Mysheet2'.B7>,
#   <Cell 'Mysheet2'.B8>,
#   <Cell 'Mysheet2'.B9>),
#  (<Cell 'Mysheet2'.C1>,
#   <Cell 'Mysheet2'.C2>,
#   <Cell 'Mysheet2'.C3>,
#   <Cell 'Mysheet2'.C4>,
#   <Cell 'Mysheet2'.C5>,
#   <Cell 'Mysheet2'.C6>,
#   <Cell 'Mysheet2'.C7>,
#   <Cell 'Mysheet2'.C8>,
#   <Cell 'Mysheet2'.C9>))
    

# 保存数据
wb.save('try_test.xlsx')
python 复制代码
# 其他
# 改变 sheet 标签按钮颜色
ws.sheet_properties.tabColor = "1072BA"

# 获得最大列和最大行
print(sheet.max_row)
print(sheet.max_column)

# 获取每一行,每一列
# 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)
        
# 根据数字得到字母,根据字母得到数字
from openpyxl.utils import get_column_letter, column_index_from_string

# 根据列的数字返回字母
print(get_column_letter(2))  # B
# 根据字母返回列的数字
print(column_index_from_string('D'))  # 4
     
# 删除工作表
# 方式一
#wb.remove(sheet)
# 方式二
#del wb[sheet]
        
# 矩阵置换(行 → 列)
rows = [
    ['Number', 'data1', 'data2'],
    [2, 40, 30],
    [3, 40, 25],
    [4, 50, 30],
    [5, 30, 10],
    [6, 25, 5],
    [7, 50, 10]]

list(zip(*rows))
# 注意 方法会舍弃缺少数据的列(行)
rows = [
    ['Number', 'data1', 'data2'],
    [2, 40      ],    # 这里少一个数据
    [3, 40, 25],
    [4, 50, 30],
    [5, 30, 10],
    [6, 25, 5],
    [7, 50, 10],
]

list(zip(*rows))

设置单元格风格

python 复制代码
# 设置单元格风格
# 1.字体
from openpyxl.styles import Font, colors, Alignment
# 下面的代码指定了等线24号,加粗bold斜体italic,字体颜色蓝色。
# 直接使用cell的font属性,将Font对象赋值给它。
bold_itatic_24_font = Font(name='等线', size=24, italic=True, color=colors.BLUE, bold=True)
sheet['A1'].font = bold_itatic_24_font

# 2.对齐方式
# 也是直接使用cell的属性aligment,这里指定垂直居中和水平居中。
# 除了center,还可以使用right、left等等参数
# 设置B1中的数据垂直居中和水平居中
sheet['B1'].alignment = Alignment(horizontal='center', vertical='center')

# 3.设置行高和列宽
# 第2行行高
sheet.row_dimensions[2].height = 80
# C列列宽
sheet.column_dimensions['C'].width = 50

# 4.合并和拆分单元格
# 所谓合并单元格,即以合并区域的左上角的那个单元格为基准,覆盖其他单元格使之称为一个大的单元格。
# 相反,拆分单元格后将这个大单元格的值返回到原来的左上角位置。

# 合并单元格, 往左上角写入数据即可
sheet.merge_cells('B1:G1') # 合并一行中的几个单元格
sheet.merge_cells('A1:C3') # 合并一个矩形区域中的单元格

# 合并后只可以往左上角写入数据,也就是区间中:左边的坐标。
# 如果这些要合并的单元格都有数据,只会保留左上角的数据,其他则丢弃。换句话说若合并前不是在左上角写入数据,合并后单元格中不会有数据。
# 以下是拆分单元格的代码。拆分后,值回到A1位置
sheet.unmerge_cells('A1:C3')


wb.save('try_test.xlsx')

过滤器和排序

python 复制代码
# 排序
from openpyxl import Workbook

wb = Workbook()
sheet = wb.active

data = [
    ['Item', 'Colour'],
    ['pen', 'brown'],
    ['book', 'black'],
    ['plate', 'white'],
    ['chair', 'brown'],
    ['coin', 'gold'],
    ['bed', 'brown'],
    ['notebook', 'white'],
]

for r in data:
    sheet.append(r)

sheet.auto_filter.ref = 'A1:B8' #设置自动筛选 筛选区域
sheet.auto_filter.add_filter_column(1, ['brown', 'white'])  # 过滤的列和需要选择的关键字
sheet.auto_filter.add_sort_condition('B2:B8')  # 为指定范围添加排序条件,默认是升序,add_sort_condition(ref, descending=False) 默认值false

wb.save('filtered.xlsx')

更改工作表的背景颜色

python 复制代码
#!/usr/bin/env python

import openpyxl

book = openpyxl.load_workbook('sheets2.xlsx')
book.create_sheet("March")
sheet = book.get_sheet_by_name("March")
sheet.sheet_properties.tabColor = "0072BA"

book.save('sheets3.xlsx')

合并单元格

python 复制代码
#!/usr/bin/env python

from openpyxl import Workbook
from openpyxl.styles import Alignment

book = Workbook()
sheet = book.active

sheet.merge_cells('A1:B2') # 合并单元格

cell = sheet.cell(row=1, column=1) #合并后单元格
cell.value = 'Sunny day'
cell.alignment = Alignment(horizontal='center', vertical='center')
# 设置文本居中

book.save('merging.xlsx')

冻结窗口

python 复制代码
#!/usr/bin/env python

from openpyxl import Workbook
from openpyxl.styles import Alignment

book = Workbook()
sheet = book.active

sheet.freeze_panes = 'B2' # 单元格 B2 冻结窗格

book.save('freezing.xlsx')

数字格式

python 复制代码
import datetime
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
# 使用Python datetime设置date
ws['A1'] = datetime.datetime(2010, 7, 21)

ws['A1'].number_format
#'yyyy-mm-dd h:mm:ss'
# 您可以根据具体情况启用类型推断
wb.guess_types = True
# 使用后跟百分比符号的字符串设置百分比
ws['B1'] = '3.14%'
ws['B1'].value

公式

openpyxl不进行计算; 它将公式写入单元格。

python 复制代码
#!/usr/bin/env python

from openpyxl import Workbook

book = Workbook()
sheet = book.active

rows = (
    (34, 26),
    (88, 36),
    (24, 29),
    (15, 22),
    (56, 13),
    (76, 18)
)

for row in rows:
    sheet.append(row)

cell = sheet.cell(row=7, column=2) # 得到显示计算结果的单元格
cell.value = "=SUM(A1:B6)"          # 将一个公式写入单元格
cell.font = cell.font.copy(bold=True) # 以粗体显示输出样式

book.save('formulas.xlsx')

图像

python 复制代码
#!/usr/bin/env python

from openpyxl import Workbook
from openpyxl.drawing.image import Image

book = Workbook()
sheet = book.active

img = Image("0.jpg") # 创建一个新的Image类,图片放在当前工作目录
sheet['A1'] = 'This is Sid'

sheet.add_image(img, 'B2') # 添加新图像

book.save("sheet_image.xlsx")

图表

openpyxl库支持各种图表:条形图,折线图,面积图,气泡图,散点图和饼图。

!!!Openpyxl目前只支持在工作表内创建图表。现有工作簿中的图表将丢失。

条形图

以下设置会影响不同的图表类型。

  1. 通过将类型分别设置为col或bar,在垂直条形图和水平条形图之间切换。
  2. 当使用堆叠图表时,重叠需要设置为100。
  3. 如果条形图是水平的,则x轴和y轴是反转的。
python 复制代码
### 垂直条形图、水平条形图
from openpyxl import Workbook
from openpyxl.chart import BarChart, Series, Reference
wb = Workbook(write_only=True)
ws = wb.create_sheet()
rows = [['Number', 'Batch 1', 'Batch 2'],[2, 30, 40],[3, 25, 40],[4 ,30, 50],[5 ,10, 30],[6, 5, 25],[7 ,10, 50],]

for row in rows:
    ws.append(row)

chart1 = BarChart()
chart1.type = "col"
chart1.style = 10
chart1.title = "Bar Chart"
chart1.y_axis.title = 'Test number'
chart1.x_axis.title = 'Sample length (mm)'

data = Reference(ws, min_col=2, min_row=1, max_row=7, max_col=3)
cats = Reference(ws, min_col=1, min_row=2, max_row=7)
chart1.add_data(data, titles_from_data=True)
chart1.set_categories(cats)
chart1.shape = 4
ws.add_chart(chart1, "A10")

from copy import deepcopy

chart2 = deepcopy(chart1)
chart2.style = 11
chart2.type = "bar"
chart2.title = "Horizontal Bar Chart"

ws.add_chart(chart2, "G10")

chart3 = deepcopy(chart1)
chart3.type = "col"
chart3.style = 12
chart3.grouping = "stacked"
chart3.overlap = 100
chart3.title = 'Stacked Chart'

ws.add_chart(chart3, "A27")

chart4 = deepcopy(chart1)
chart4.type = "bar"
chart4.style = 13
chart4.grouping = "percentStacked"
chart4.overlap = 100
chart4.title = 'Percent Stacked Chart'

ws.add_chart(chart4, "G27")

wb.save("bar.xlsx")

折线图

python 复制代码
### 折线图
from datetime import date
from openpyxl import Workbook
from openpyxl.chart import (
    LineChart,
    Reference,
)
from openpyxl.chart.axis import DateAxis

wb = Workbook()
ws = wb.active

rows = [
    ['Date', 'Batch 1', 'Batch 2', 'Batch 3'],
    [date(2015,9, 1), 40, 30, 25],
    [date(2015,9, 2), 40, 25, 30],
    [date(2015,9, 3), 50, 30, 45],
    [date(2015,9, 4), 30, 25, 40],
    [date(2015,9, 5), 25, 35, 30],
    [date(2015,9, 6), 20, 40, 35],
]

for row in rows:
    ws.append(row)

c1 = LineChart()
c1.title = "Line Chart"
c1.style = 13
c1.y_axis.title = 'Size'
c1.x_axis.title = 'Test Number'

data = Reference(ws, min_col=2, min_row=1, max_col=4, max_row=7)
c1.add_data(data, titles_from_data=True)

# 线类型
s1 = c1.series[0]
s1.marker.symbol = "triangle"
s1.marker.graphicalProperties.solidFill = "FF0000" # 标记填充
s1.marker.graphicalProperties.line.solidFill = "FF0000" # 标志的轮廓

s1.graphicalProperties.line.noFill = True

s2 = c1.series[1]
s2.graphicalProperties.line.solidFill = "00AAAA"
s2.graphicalProperties.line.dashStyle = "sysDot"
s2.graphicalProperties.line.width = 100050 # 宽度在EMUs

s2 = c1.series[2]
s2.smooth = True # 使线条平滑

ws.add_chart(c1, "A10")

from copy import deepcopy

stacked = deepcopy(c1)
stacked.grouping = "stacked"
stacked.title = "Stacked Line Chart"
ws.add_chart(stacked, "A27")

percent_stacked = deepcopy(c1)
percent_stacked.grouping = "percentStacked"
percent_stacked.title = "Percent Stacked Line Chart"
ws.add_chart(percent_stacked, "A44")

# 带日期轴的图表
c2 = LineChart()
c2.title = "Date Axis"
c2.style = 12
c2.y_axis.title = "Size"
c2.y_axis.crossAx = 500
c2.x_axis = DateAxis(crossAx=100)
c2.x_axis.number_format = 'd-mmm'
c2.x_axis.majorTimeUnit = "days"
c2.x_axis.title = "Date"

c2.add_data(data, titles_from_data=True)
dates = Reference(ws, min_col=1, min_row=2, max_row=7)
c2.set_categories(dates)

ws.add_chart(c2, "A61")

wb.save("line.xlsx")


散点图

python 复制代码
### 散点图
from openpyxl import Workbook
from openpyxl.chart import (
    ScatterChart,
    Reference,
    Series,
)

wb = Workbook()
ws = wb.active

rows = [
    ['Size', 'Batch 1', 'Batch 2'],
    [2, 40, 30],
    [3, 40, 25],
    [4, 50, 30],
    [5, 30, 25],
    [6, 25, 35],
    [7, 20, 40],
]

for row in rows:
    ws.append(row)

chart = ScatterChart()
chart.title = "Scatter Chart"
chart.style = 13
chart.x_axis.title = 'Size'
chart.y_axis.title = 'Percentage'

xvalues = Reference(ws, min_col=1, min_row=2, max_row=7)
for i in range(2, 4):
    values = Reference(ws, min_col=i, min_row=1, max_row=7)
    series = Series(values, xvalues, title_from_data=True)
    
    #设置系列1数据点的样式,圆圈
    series.marker.symbol = "circle"
    #设置系列1数据点的颜色,以下两行代码将其改为红色
    series.marker.graphicalProperties.solidFill = "FF0000"  # 点的内部填充颜色
    series.marker.graphicalProperties.line.solidFill = "FF0000"  #点的外边框颜色
 
    #关键的一步:关闭系列1数据点之间的连接线 否则画出来类似折线图
    series.graphicalProperties.line.noFill = True
    
    
    chart.series.append(series)

ws.add_chart(chart, "A10")

wb.save("scatter.xlsx")

其他图表参考链接3。

参考1: python之openpyxl模块(最全总结 足够初次使用)

参考2: Openpyxl 教程

参考3: openpyxl官方教程参考手册(翻译)

相关推荐
浦信仿真大讲堂22 分钟前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
hPw0eKIqD23 分钟前
使用二次封装的Excel COM 组件操作Excel\WPS ET中的区域、行和列
excel·wps
Gu Gu Study1 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境2 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境2 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1232 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102162 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb003 小时前
一个项目带你入门AI应用开发01
python
0566463 小时前
Python康复训练——常用标准库
开发语言·python·学习
wechatbot8883 小时前
企业微信API开发:登录-联系人查询-消息发送完整开发流程分享
汇编·微信·自动化·企业微信·ai编程·rpa