openpyxl设置单元格样式必须使用font、patternfill、border等类的实例,不能直接赋值字符串;需逐个属性赋值且遍历每个单元格,合并单元格后须手动补全样式,条件格式需用conditional_formatting而非手动设置。

openpyxl 中设置单元格样式的正确入口是 Font、PatternFill、Border 等独立类,不是直接赋值字符串
很多人一上来就写 cell.style = "Bold" 或 cell.font = "Calibri",结果报错或无效。openpyxl 的样式必须用对应类的实例,且需完整构造——比如加粗要写 Font(bold=True),而不是传字符串。
常见错误现象:AttributeError: 'str' object has no attribute 'name'(传了字符串给 font)、样式不生效(忘了重新赋值给 cell.font 等属性)、整列样式丢失(只改了部分行,没循环到位)。
实操建议:
- 所有样式对象都需显式实例化:
Font(name="微软雅黑", size=10, bold=True)、PatternFill("solid", fgColor="FFD700")、Border(left=Side(style="thin")) - 样式必须逐个属性赋值:
cell.font = my_font、cell.fill = my_fill、cell.border = my_border - 避免重复创建样式对象:如果给 1000 个单元格设相同字体,先建一个
Font实例复用,别在循环里反复 new
批量设置整行/整列/区域样式时,必须遍历每个 Cell 对象,不能只操作 Row 或 Column 对象
ws.row_dimensions[1].font 这类写法无效——openpyxl 不支持对行/列维度统一设字体或填充色。样式只存在于具体单元格上,哪怕你只想让第 2 行全加背景色,也得遍历 ws[2] 中每个 cell。
使用场景举例:导出报表时,给标题行加粗+居中+浅灰底;给数值列右对齐;给异常数据行标红底。
实操建议:
- 设整行:
for cell in ws[3]: cell.font = title_font; cell.alignment = Alignment(horizontal="center") - 设整列:
for row in ws.iter_rows(min_col=5, max_col=5, min_row=2, max_row=ws.max_row): for cell in row: cell.number_format = "0.00%" - 设矩形区域:
for row in ws["B2:D100"]: for cell in row: cell.border = thin_border
合并单元格后样式只保留在左上角单元格,其余位置样式为空,需手动补全
这是 openpyxl 最容易被忽略的坑。执行 ws.merge_cells("A1:C1") 后,只有 ws["A1"] 保留你设的样式,ws["B1"] 和 ws["C1"] 的 font/fill 都是 None。如果后续代码又去读取 B1 的样式,会出错或显示默认值。
性能影响:手动补全样式会让合并区域的样式设置成本翻倍(比如合并 1×10 区域,要设 10 次),但无法绕过。
实操建议:
- 合并前先存好样式:
orig_style = ws["A1"].font - 合并后立即补全:
for cell in ws["A1:C1"][0]: cell.font = orig_style - 更稳妥的做法:封装一个
merge_and_style(ws, "A1:C1", font=..., fill=...)函数,内部自动处理补全
openpyxl 样式不支持条件格式的“动态计算”,真要实现高亮规则得靠 worksheet.conditional_formatting
有人想“把大于 100 的单元格自动标红”,试图用循环判断 + 手动设 fill,这在小数据量下可行,但一旦表格超 5000 行,性能骤降,而且 Excel 文件打开后不会随数值变化自动更新——它只是静态样式。
真正和 Excel 原生“条件格式”一致的行为,必须用 ConditionalFormattingRule:
from openpyxl.formatting import Rule
from openpyxl.styles import Font, PatternFill
rule = Rule(
type="cellIs",
operator="greaterThan",
formula=["100"],
font=Font(color="FF0000"),
fill=PatternFill(fill_type="solid", bgColor="FFCCCCCC")
)
ws.conditional_formatting.add("B2:B1000", rule)
注意:formula 是字符串列表,即使单个条件也要写成 ["100"];bgColor 值不含透明度前缀(即填 "FFD700",不是 "#FFD700");条件格式添加后无法用 ws["B2"].fill 读取到——它是独立于单元格样式的另一套机制。
容易被忽略的是:条件格式规则在保存后才生效,且某些旧版 Excel 可能不识别 type="containsText" 这类高级规则。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











