Python - openpyxl Excel 操作示例与实践

简介: Python openpyxl库常用操作与实例分析~

 一.引言

使用脚本处理得到数据后需要转化至 excel,由于手动粘贴以及换行符的问题非常不智能,所以改用 openpyxl 库处理脚本得到的数据并完成标注,顺便介绍下 openpyxl 的常用语法,先看下我们的原始数据:

A B C D
0.012 0.951 0.234 -0.137
0.038 0.999 -0.225 0.139

image.gif

其中 A,B,C,D 为表头,下两列为小数点比例,我们想要达到的效果:

(1) 小数转化为百分数且保留1位小数

(2) 大于0的百分数标记为红色,小于0的数标记为绿色

(3) 数字在表中对齐

image.gif编辑

下面来熟悉下 openpyxl 的常用操作并实现上述需求~

二.openpyxl 常规操作

1.创建 WorkBook

Workbook 类为 openpyxl 的基础类,初始化该类可以理解为打开一个全新的 excel 工作区,其中 create_sheet 可以视作新建一个 sheet,下述示例创建一个名为 Sheet1 的表格,一个 Workbook 可以初始化多个 sheet:

# 初始化
workbook = Workbook()
# 创建 sheet
sheet = workbook.create_sheet("Sheet")

image.gif

2.sheet 添加数据

A.单点添加

sheet 对应 Sheet 类,其中表格中的每一个单元格对应 Cell 类,可以通过 Sheet['position'] = xxx 设定单元格的值,随后通过 Cell.value 获取对应单元格的值,position 需要通过 excel 类似的索引进行设定,例如 'A1', 'B10','AA5',而获取 cell 则需要通过 (row, col) 索引,这里有一些不同。

image.gif编辑

例如我想在 D7 位置设置为 999,则可以执行 sheet['D7'] = 999。

sheet['D7'] = 999

image.gif

B.批量添加

sheet = workbook.create_sheet("Sheet", 0)
sheet.append([1, 2, 3, 4])
sheet.append([2, 3, 4, 5])
sheet.append([3, 4, 5, 6])

image.gif

该方法会逐行添加数组的数据:

image.gif编辑

数组不等长也可以:

sheet.append([1, 2, 3, 4])
sheet.append([2, 3, 4, 5, 6])
sheet.append([3, 4, 5, 6])

image.gif

image.gif编辑

3.获取 sheet 数据

上面提到每个单元格的数据为 Cell,需要通过 sheet.cell(row, col) 方法获得,这里需要注意 excel 的行列索引都是从1开始,从 0 开始遍历会报错。下面获取 D7 的值:

cell = sheet.cell(7, 4)
print(cell.value)

image.gif

999

image.gif

4.行列转换

上面添加值采用的坐标系是 A-col 5-row 这种字母+数字的组合,而获取 Cell 单元格采取的是 10-row 2-col 这样的坐标形式,因此二者关联涉及到 col 的转换问题。这里 openpyxl 库提供了 util 函数,只需调用即可得到 index- string 的转换:

from openpyxl.utils import get_column_letter, column_index_from_string
num = 10
# index 转换为 字符
index2string = get_column_letter(num)
# 字符转换为 index
string2index = column_index_from_string(index2string)
print(num, "->", index2string)
print(index2string, "->", string2index)

image.gif

10 -> J
J -> 10

image.gif

image.gif编辑

5.访问多行,多列

A.切片访问

for i in sheet['A1':'A10']:
    cell = i

image.gif

(<Cell 'Sheet1'.A1>,)
(<Cell 'Sheet1'.A2>,)
(<Cell 'Sheet1'.A3>,)
(<Cell 'Sheet1'.A4>,)
(<Cell 'Sheet1'.A5>,)
(<Cell 'Sheet1'.A6>,)
(<Cell 'Sheet1'.A7>,)
(<Cell 'Sheet1'.A8>,)
(<Cell 'Sheet1'.A9>,)
(<Cell 'Sheet1'.A10>,)

image.gif

上述代码访问 A列的 1-10 行,对应下图所示区域:

image.gif编辑

 同理也可以用切片访问同一行的数据:

for i in sheet['A1':'D1']:
    cell = i

image.gif

(<Cell 'Sheet1'.A1>, <Cell 'Sheet1'.B1>, <Cell 'Sheet1'.C1>, <Cell 'Sheet1'.D1>)

image.gif

image.gif编辑

B.区域遍历

对指定表格区域进行遍历,选取 row 和 col 的大小区间即可遍历对应区域内元素:

for row in sheet.iter_rows(min_row=5, max_row=8, min_col=1, max_col=3):
    for cell in row:
        print(cell)

image.gif

<Cell 'Sheet1'.A5>
<Cell 'Sheet1'.B5>
<Cell 'Sheet1'.C5>
<Cell 'Sheet1'.A6>
<Cell 'Sheet1'.B6>
<Cell 'Sheet1'.C6>
<Cell 'Sheet1'.A7>
<Cell 'Sheet1'.B7>
<Cell 'Sheet1'.C7>
<Cell 'Sheet1'.A8>
<Cell 'Sheet1'.B8>
<Cell 'Sheet1'.C8>

image.gif

上述代码访问 1-3 列即 A-C 列,5-8 行,元素对应下述方框:

image.gif编辑

C.全局遍历

遍历 rows 或者 cols 其实都是遍历整个 sheet。

# 从 row 的角度遍历 sheet
for rows in sheet.rows:
    for row in rows:
        print(row.value)
# 从 col 的角度遍历 sheet
for cols in sheet.columns:
    for col in cols:
        print(col.value)

image.gif

image.gif编辑

6.获取行列数

# 获取行列数
rowNum = sheet.max_row
colNum = sheet.max_column
print("row: ", rowNum, "col: ", colNum)

image.gif

row: 8 col: 4

image.gif

7.使用公式

A.单点使用公式

下述命令定义 C15 处的值为 5 + 5 = 10

sheet['C15'] = '=sum({}, {})'.format(5, 5)

image.gif

image.gif编辑

B.批量使用公式

先创建一个新表格 sheet2,然后列名分别为 Name,Score 并添加对应值:

sheet2 = workbook.create_sheet("Sheet2", 0)
sheet2['A1'] = "Name"
sheet2['B1'] = "Score"
sheet2.append(['A', 1])
sheet2.append(['B', 2])
sheet2.append(['C', 3])
sheet2['C1'] = "Add_1"

image.gif

image.gif编辑

下面应用公式,其中 Add_1 列的数据为 B2-B4 的值+1:

for row in range(2, 5):
    colLetter = get_column_letter(3)
    sheet2[colLetter + str(row)] = '=sum({}, {})'.format(sheet2.cell(row, 2).value, 1)

image.gif

image.gif编辑

8.保存,读取,删除表格

其中 file_path 为对应表格的存储,删除位置:

# 保存表
workbook.save(file_path)
# 删表
workbook.remove(file_path)
# 读取sheet
wb = openpyxl.load_workbook(file_path)
sheet = wb.get_sheet_by_name(sheet_name)

image.gif

三.openpyxl 样式操作

1.简介

上面介绍了如何向表格添加数据,以及对表格的数据进行遍历,处理,下面针对表格样式进行分析,现在我们知道每一个单元格对应一个 Cell Class 即 from openpyxl.cell import Cell :

image.gif编辑

cell 除了调用 .value 方法获取其对应值外,还可以修改如下格式:

A. font - 字体相关

B. fill - 填充颜色相关

C.alignment - 对齐相关

D.border - 边界相关

E.comment - 注释相关

下述示例基于上一步 append 得到的基本 sheet:

image.gif编辑

2.font 字体

下面对 B2 位置的 cell 切换为 黑体简 11号 加粗 红色 字体:

cell = sheet.cell(column=2, row=2)
# 指定 font 字体名 name + 大小 size + 加粗 blod + 斜体 italic + 颜色 color
font = Font(name='黑体简', size=11, italic=False, color="FF0000", bold=True)
cell.font = font

image.gif

image.gif编辑

这里参数含义为:

name 字体
size 大小
italic 斜体
blod 加粗
color 颜色

字体样式等参数详情也可以直接去 excel 里看,可以提前看看效果:

image.gif编辑

3.fill 填充相关

fill 主要负责单元格填充颜色,下面分别使用完整填充和渐变填充对单元格进行填充:

A.(2-3)位置填充完灰色 PatternFill

fgColor 为对应颜色的编码

cell = sheet5.cell(row=2, column=3)
cell.fill = PatternFill("solid", fgColor="00778899")

image.gif

B.(2-4)位置填充为红绿渐变

stop 内也可以添加多种颜色,会实现多层次渐变

cell2 = sheet5.cell(row=2, column=4)
cell2.fill = GradientFill(stop=("007CFC00", "00FF4500"))

image.gif

image.gif编辑

4.alignment 对齐相关

alignment = Alignment(horizontal="center", vertical="center", 
                      text_rotation=0, wrap_text=False)
cell = sheet.cell(row=2, column=3)
cell.alignment = alignment

image.gif

对 (2,3)位置的元素进行居中处理,参数含义为:

horizontal 水平对齐模式
vertical 垂直对齐模式
text_rotation 旋转角度
wrap_text 是否自动换行

image.gif编辑

5.border 边界相关

对 (2,4)位置元素加边界,上下分别为绿色和黑色细线,左右分别为红绿双线:

cell = sheet.cell(row=2, column=4)
cell.border = Border(left=Side(style='double', color="FF0000"),
                     right=Side(style='double', color="0000FF"),
                     top=Side(style='thin', color="00FF00"),
                     bottom=Side(style='thin'))

image.gif

image.gif编辑

Border 内共包含 left,right,top,bottom 即上下左右四个方位的边界线

SIde 为对应边界线属性,style 比较多,填写 style 随便填一个代码就会报错,随后异常栈就会打出当前版本支持的 style 属性,根据需求选取即可:

ValueError: Value must be one of {'dotted', 'dashed', 'mediumDashDotDot', 
'double', 'thick', 'dashDot', 'medium', 'slantDashDot', 'mediumDashDot', 'thin', 
'dashDotDot', 'hair', 'mediumDashed'}

image.gif

6.comment 注释相关

对 (1,1)位置元素进行注释,第一个参数为注释内容,第二个参数为对应 Author:

# 注释
cell = sheet.cell(row=1, column=1)
comment = Comment("This is a comment!", "DDD")
cell.comment = comment

image.gif

image.gif编辑

7.height-width 相关

sheet5.row_dimensions[1].height = 50
sheet5.column_dimensions['B'].width = 20

image.gif

调整 'B'列 和 '1'行 单元格的行宽和列高:

image.gif编辑

8.合并与取消合并单元格

A.合并单元格

sheet.merge_cells("C1:D2")

image.gif

以 C1 为边框左上角,D2 为边框右下角进行单元格合并,数据会保留为 C1 对应的 Value:

image.gif编辑

B.取消合并单元格

sheet.unmerge_cells("C1:D2")

image.gif

单元格解除合并,但是其余单元格的数据不会回补

image.gif编辑

四.openpyxl 实践

1.案例需求

经过上面的讲解分析,已经熟悉了 openpyxl 的基本操作,下面回归到引言中提到的问题,我们需要将下述数据:

A B C D
0.012 0.951 0.234 -0.137
0.038 0.999 -0.225 0.139

image.gif

转换为:

image.gif编辑

这里浅分析一下转化的过程:

A.初始化 Workbook 与 Sheet

B.通过 row,col 将对应元素添加至 Sheet 对应位置

C.大于 0 的值对应位置 Cell 颜色更改为红色,小于 0 更改为绿色

D.全部单元格居中对齐

E.保留1位小数

2.案例实现

def colorFulData(_sheet, _head, _values):
    # 定义字体
    _font = None
    # 获取 values 的长款
    _colNum = len(_head)
    _rowNum = len(_values)
    # 定义对齐方式
    _alignment = Alignment(horizontal="center", vertical="center", text_rotation=0, wrap_text=False)
    for _col in range(1, _colNum + 1):
        # col 转换并添加元素到 Cell
        _sheet[get_column_letter(_col) + str(1)] = head[_col - 1]
        _cell = _sheet.cell(1, _col)
        _cell.alignment = _alignment
        for _row in range(1, _rowNum + 1):
            # 保留一位小数
            _sheet[get_column_letter(_col) + str(_row + 1)] = format(values[_row - 1][_col - 1], '.1%')
            _cell = _sheet.cell(_row + 1, _col)
            numValue = float(values[_row - 1][_col - 1])
            # 根据值改变字体颜色
            if numValue > float(0):
                _font = Font(name='黑体简', size=11, italic=False, color="00FF0000", bold=True)
            elif numValue < float(0):
                _font = Font(name='黑体简', size=11, italic=False, color="0000FF00", bold=True)
            _cell.font = _font
            _cell.alignment = _alignment
head = ["A", "B", "C", "D"]
values = [[0.012, 0.951, 0.234, -0.137], [0.038, 0.999, -0.225, 0.139]]
colorFulData(sheet, head, values)
workbook.save(file_path)

image.gif

只需要传入表头和对应的 values 数据即可,这里没有 try catch,因此输入的 value 应该是合法的形式,否则会报错,更多的字体样式,单元格合并,单元格填充等也可以添加到上面对应 Cell 中,下面是基础形式的实现得到的效果:

image.gif编辑

五.openpyxl 拓展

上面单元格的 color 或者是填充的 color 都用到了颜色代码,下面给出一些常用的颜色编码,有需要的可以应用到自己的程序内:

'00F0F8FF', '00FAEBD7', '0000FFFF', '007FFFD4', '00F0FFFF', '00F5F5DC', 
    '00FFE4C4', '00000000', '00FFEBCD', '000000FF', '008A2BE2', '00A52A2A', 
    '00DEB887', '005F9EA0', '007FFF00', '00D2691E', '00FF7F50', '006495ED',
    '00FFF8DC', '00DC143C', '0000FFFF', '0000008B', '00008B8B', '00B8860B', 
    '00A9A9A9', '00006400', '00BDB76B', '008B008B', '00556B2F', '00FF8C00',
    '009932CC', '008B0000', '00E9967A', '008FBC8F', '00483D8B', '002F4F4F',
    '0000CED1', '009400D3', '00FF1493', '0000BFFF', '00696969', '001E90FF', 
    '00B22222', '00FFFAF0', '00228B22', '00FF00FF', '00DCDCDC', '00F8F8FF', 
    '00FFD700', '00DAA520', '00808080', '00008000', '00ADFF2F', '00F0FFF0', 
    '00FF69B4', '00CD5C5C', '004B0082', '00FFFFF0', '00F0E68C', '00E6E6FA', 
    '00FFF0F5', '007CFC00', '00FFFACD', '00ADD8E6', '00F08080', '00E0FFFF', 
    '00FAFAD2', '0090EE90', '00D3D3D3', '00FFB6C1', '00FFA07A', '0020B2AA', 
    '0087CEFA', '00778899', '00B0C4DE', '00FFFFE0', '0000FF00', '0032CD32', 
    '00FAF0E6', '00FF00FF', '00800000','0066CDAA', '000000CD', '00BA55D3', 
    '009370DB', '003CB371', '007B68EE', '0000FA9A', '0048D1CC', '00C71585',
    '00191970', '00F5FFFA', '00FFE4E1', '00FFE4B5', '00FFDEAD', '00000080', 
    '00FDF5E6', '00808000', '006B8E23', '00FFA500', '00FF4500', '00DA70D6', 
    '00EEE8AA', '0098FB98', '00AFEEEE', '00DB7093', '00FFEFD5', '00FFDAB9',
    '00CD853F', '00FFC0CB', '00DDA0DD', '00B0E0E6', '00800080', '00FF0000', 
    '00BC8F8F', '004169E1', '008B4513', '00FA8072', '00FAA460', '002E8B57', 
    '00FFF5EE', '00A0522D', '00C0C0C0', '0087CEEB', '006A5ACD', '00708090',
    '00FFFAFA', '0000FF7F', '004682B4', '00D2B48C', '00008080', '00D8BFD8', 
    '00FF6347', '0040E0D0', '00EE82EE', '00F5DEB3', '00FFFFFF', '00F5F5F5', 
    '00FFFF00', '009ACD32'

image.gif

这里简单修改一下程序就可以得到上述代码对应的真实颜色,还是有很多好看的颜色可以选择:

image.gif编辑

目录
相关文章
|
8天前
|
Python
深入理解Python装饰器:从入门到实践####
本文旨在通过简明扼要的方式,为读者揭开Python装饰器的神秘面纱,从基本概念、工作原理到实际应用场景进行全面解析。不同于常规的摘要仅概述内容概要,本文将直接以一段精炼代码示例开篇,展示装饰器如何优雅地增强函数功能,激发读者探索兴趣,随后深入探讨其背后的机制与高级用法。 ####
38 11
|
5天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能浪潮下的自我修养:从Python编程入门到深度学习实践
【10月更文挑战第39天】本文旨在为初学者提供一条清晰的道路,从Python基础语法的掌握到深度学习领域的探索。我们将通过简明扼要的语言和实际代码示例,引导读者逐步构建起对人工智能技术的理解和应用能力。文章不仅涵盖Python编程的基础,还将深入探讨深度学习的核心概念、工具和实战技巧,帮助读者在AI的浪潮中找到自己的位置。
|
1月前
|
存储 程序员 开发者
Python编程基础:从入门到实践
【10月更文挑战第8天】在本文中,我们将一起探索Python编程的奇妙世界。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供有价值的信息。我们将从Python的基本概念开始,然后逐步深入到更复杂的主题,如数据结构、函数和类。最后,我们将通过一些实际的代码示例来巩固我们的知识。让我们一起开始这段Python编程之旅吧!
|
4天前
|
设计模式 缓存 开发框架
Python中的装饰器:从入门到实践####
本文深入探讨了Python中装饰器的工作原理与应用,通过具体案例展示了如何利用装饰器增强函数功能、提高代码复用性和可读性。读者将学习到装饰器的基本概念、实现方法及其在实际项目开发中的实用技巧。 ####
17 3
|
8天前
|
机器学习/深度学习 数据采集 数据可视化
Python在数据科学中的应用:从入门到实践
本文旨在为读者提供一个Python在数据科学领域应用的全面概览。我们将从Python的基础语法开始,逐步深入到数据处理、分析和可视化的高级技术。文章不仅涵盖了Python中常用的数据科学库,如NumPy、Pandas和Matplotlib,还探讨了机器学习库Scikit-learn的使用。通过实际案例分析,本文将展示如何利用Python进行数据清洗、特征工程、模型训练和结果评估。此外,我们还将探讨Python在大数据处理中的应用,以及如何通过集成学习和深度学习技术来提升数据分析的准确性和效率。
|
7天前
|
数据采集 IDE 测试技术
Python实现自动化办公:从基础到实践###
【10月更文挑战第21天】 本文将探讨如何利用Python编程语言实现自动化办公,从基础概念到实际操作,涵盖常用库、脚本编写技巧及实战案例。通过本文,读者将掌握使用Python提升工作效率的方法,减少重复性劳动,提高工作质量。 ###
22 1
|
8天前
|
机器学习/深度学习 数据采集 人工智能
探索机器学习:从理论到Python代码实践
【10月更文挑战第36天】本文将深入浅出地介绍机器学习的基本概念、主要算法及其在Python中的实现。我们将通过实际案例,展示如何使用scikit-learn库进行数据预处理、模型选择和参数调优。无论你是初学者还是有一定基础的开发者,都能从中获得启发和实践指导。
19 2
|
11天前
|
算法 Python
Python图论探索:从理论到实践,DFS与BFS遍历技巧让你秒变技术大牛
图论在数据结构与算法中占据重要地位,应用广泛。本文通过Python代码实现深度优先搜索(DFS)和广度优先搜索(BFS),帮助读者掌握图的遍历技巧。DFS沿路径深入搜索,BFS逐层向外扩展,两者各具优势。掌握这些技巧,为解决复杂问题打下坚实基础。
24 2
|
11天前
|
搜索推荐 Python
快速排序的 Python 实践:从原理到优化,打造你的排序利器!
本文介绍了 Python 中的快速排序算法,从基本原理、实现代码到优化方法进行了详细探讨。快速排序采用分治策略,通过选择基准元素将数组分为两部分,递归排序。文章还对比了快速排序与冒泡排序的性能,展示了优化前后快速排序的差异。通过这些分析,帮助读者理解快速排序的优势及优化的重要性,从而在实际应用中选择合适的排序算法和优化策略,提升程序性能。
24 1
|
12天前
|
Python
探索Python装饰器:从入门到实践
【10月更文挑战第32天】在编程世界中,装饰器是一种特殊的函数,它允许我们在不改变原有函数代码的情况下,增加额外的功能。本文将通过简单易懂的语言和实际案例,带你了解Python中装饰器的基础知识、应用以及如何自定义装饰器,让你的代码更加灵活和强大。
16 2