You can control font attributes like name, size, bold, italic, color, etc., using the Font class from openpyxl.styles, as below:
from openpyxl import Workbook
from openpyxl.styles import Font
workbook = Workbook()
sheet = workbook.active
sheet["A1"] = "Styled Text"
my_font = Font(
name = "Arial",
size = 20,
bold = True,
italic = True,
underline = "double",
strikethrough = True,
shadow = True,
color = "0000FF"
)
sheet["A1"].font = my_font
workbook.save("font_styles.xlsx")
Source code reference:
Font class: https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/default/openpyxl/styles/fonts.py?ref_type=heads#L32Default Font Styles:
DEFAULT_FONT = Font(name="Calibri", sz=11, family=2, b=False, i=False,
color=Color(theme=1), scheme="minor")
Referece on underline:
u = NestedNoneSet(values=('single', 'double', 'singleAccounting',
'doubleAccounting'))
underline = Alias("u")
Note: the color can be specified using RGB hex codes (e.g., “FF0000” for red) or named colors(?), from documentation (https://openpyxl.pages.heptapod.net/openpyxl/styles.html#colours), you can find aRGB colours and Indexed Colours. (need test on the named colors)
Cell background colors are controlled with the PatternFill class:
from openpyxl import Workbook
from openpyxl.styles import PatternFill
workbook = Workbook()
sheet = workbook.active
sheet["A1"] = "Yellow Fill"
# Solid Fill Style
my_fill1 = PatternFill(
start_color = "FFFF00",
end_color = "FFFF00",
fill_type = "solid"
)
sheet["A1"].fill = my_fill1
sheet["B2"] = "Light Up Blue"
# Solid Fill Style
my_fill2 = PatternFill(
start_color = "0000FF",
end_color = "FFFFFF",
fill_type = "lightUp"
)
sheet["B2"].fill = my_fill2
workbook.save("fill_styles.xlsx")
Source code reference:
PatternFill(Fill) is inherit from class Fill: https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/default/openpyxl/styles/fills.py?ref_type=heads#L68fill_type: https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/default/openpyxl/styles/fills.py?ref_type=heads#L42Fill Color Naming Conversion Mapping with Excel:
| Fill Pattern Full Name | Short Name | Name in Excel |
|---|---|---|
| FILL_SOLID | solid | Solid |
| FILL_PATTERN_DARKDOWN | darkDown | Reverse Diagonal Stripe |
| FILL_PATTERN_DARKGRAY | darkGray | 75% Gray |
| FILL_PATTERN_DARKGRID | drakGrid | Diagonal Crosshatch |
| FILL_PATTERN_DARKHORIZONTAL | darkHorizontal | Horizontal Stripe |
| FILL_PATTERN_DARKTRELLIS | darkTrellis | Thick Diagonal Crosshatch |
| FILL_PATTERN_DARKUP | darkUp | Diagonal Stripe |
| FILL_PATTERN_DARKVERTICAL | darkVertical | Vertical Stripe |
| FILL_PATTERN_GRAY0625 | gray0625 | 6.25% Gray |
| FILL_PATTERN_GRAY125 | gray125 | 12.5% Gray |
| FILL_PATTERN_LIGHTDOWN | lightDown | Thin Reverse Diagonal Stripe |
| FILL_PATTERN_LIGHTGRAY | lightGray | 25% Gray |
| FILL_PATTERN_LIGHTGRID | lightGrid | Thin Horizontal Crosshatch |
| FILL_PATTERN_LIGHTHORIZONTAL | lightHorizontal | Thin Horizontal Stripe |
| FILL_PATTERN_LIGHTTRELLIS | lightTrellis | Thing Diagonal Crosshatch |
| FILL_PATTERN_LIGHTUP | lightUp | Thin Diagonal Stripe |
| FILL_PATTERN_LIGHTVERTICAL | lightVertical | Thin Vertical Stripe |
| FILL_PATTERN_MEDIUMGRAY | mediumGray | 50% Gray |
Borders are defined using the Border, Side classes:
from openpyxl import Workbook
from openpyxl.styles import Border, Side
workbook = Workbook()
sheet = workbook.active
sheet["B2"] = "Thin Border"
sheet["D2"] = "Thick Border"
thin_border = Border(
left = Side(style = 'thin'),
right = Side(style = 'thin'),
top = Side(style = 'thin'),
bottom = Side(style = 'dashDotDot', color = "0000FF")
)
thick_border = Border(
left = Side(style = 'thick', color = "FF0000"),
right = Side(style = 'thick'),
top = Side(style = 'thick'),
bottom = Side(style = 'thick', color = "0000FF")
)
sheet["B2"].border = thin_border
sheet["D2"].border = thick_border
workbook.save("border_styles.xlsx")
Soruce code reference:
Border in borders.py: https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/default/openpyxl/styles/borders.py?ref_type=heads#L54
border_style = Alias('style')Side in borders.py: https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/default/openpyxl/styles/borders.py?ref_type=heads#L33
Side style=NoneSet(): https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/default/openpyxl/styles/borders.py?ref_type=heads#L41Valid Border Side Styles:
style = NoneSet(values=('dashDot','dashDotDot', 'dashed','dotted',
'double','hair', 'medium', 'mediumDashDot', 'mediumDashDotDot',
'mediumDashed', 'slantDashDot', 'thick', 'thin'))
Cell content alignment is controlled with the Alignment class:
from openpyxl import Workbook
from openpyxl.styles import Alignment
workbook = Workbook()
sheet = workbook.active
sheet["C5"] = "Center Aligned Text"
my_alignment = Alignment(
horizontal = "center",
vertical = "top",
wrapText = True
)
sheet["C5"].alignment = my_alignment
workbook.save("alignment_styles.xlsx")
Source code reference:
Alignment in alignment.py: https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/default/openpyxl/styles/alignment.py?ref_type=heads#L16horizontal_alignments = (
"general", "left", "center", "right", "fill", "justify", "centerContinuous",
"distributed", )
vertical_aligments = (
"top", "center", "bottom", "justify", "distributed",
)
Number formate were covered in the previous section (“Cells and Cell Values”).
Conditional formatting involves applying styles based on cell values or formulas.
openpyxl provides support for this, but it’s more complex; here in openpyxl documentation (https://openpyxl.pages.heptapod.net/openpyxl/formatting.html).
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Border, Color
from openpyxl.styles.differential import DifferentialStyle
from openpyxl.formatting.rule import ColorScaleRule, CellIsRule, FormulaRule
wb = Workbook()
ws = wb.active
# Create fill
redFill = PatternFill(
start_color = "EE1111",
end_color = "EE1111",
fill_type = "solid"
)
# Add a two-color scale
ws.conditional_formatting.add(
"A1:A10",
ColorScaleRule(
start_type = "min",
start_color = "AA0000",
end_type = "max",
end_color = "00AA00"
)
)
# Add a three-color scale
ws.conditional_formatting.add(
"B1:B10",
ColorScaleRule(
start_type = "percentile",
start_value = 10,
start_color = "FF0000",
mid_type = "percentile",
mid_value = 50,
mid_color = "0000FF",
end_type = "percentile",
end_value = 90,
end_color = "00AA00"
)
)
# Formatting baed on a cell comparison
ws.conditional_formatting.add(
"C2:C10",
CellIsRule(
operator = "between",
formula = ['1', '5'],
stopIfTrue = True,
fill = redFill
)
)
myFont = Font()
myBorder = Border()
ws.conditional_formatting.add(
"D1:D10",
FormulaRule(
formula = ["E1=0"],
font = myFont,
border = myBorder,
fill = redFill
)
)
wb.save("conditional-formatting.xlsx")
Source code reference:
DifferentialStyle in differential.py: https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/default/openpyxl/styles/differential.py?ref_type=heads#L19rule.py:
ColorScaleRule: https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/default/openpyxl/formatting/rule.py?ref_type=heads#L214FormulaRule: https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/default/openpyxl/formatting/rule.py?ref_type=heads#L243CellIsRule: https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/default/openpyxl/formatting/rule.py?ref_type=heads#L253openpyxl allows working with styles and themes, but the specifics are advanced and are best explored in the library’s documentation. Themes govern the overall look and feel, while styles provide more fine-grained control over individual elements.
Styles are applied to cells using the appropriate style properties (e.g., cell.font, cell.fill, cell.alignment, cell.number_format, cell.border). To apply styles to ranges, iterate through the cells in the range and apply the styles to each cell individually, or explore using Conditional Formatting which can apply styles to ranges based on conditions. Creating and applying a custom Style object can also be helpful for consistently applying multiple formatting elements.
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Border, Side, Alignment
workbook = Workbook()
sheet = workbook.active
# Define styles once
bold_red_font = Font(bold = True, color = "FF0000")
yellow_fill = PatternFill(
start_color = "FFFF00",
end_color = "FFFF00",
fill_type = "solid"
)
thin_border = Border(
left = Side(style = "thin"),
right = Side(style = "thin"),
top = Side(style = "thin"),
bottom = Side(style = "thick")
)
center_alignment = Alignment(horizontal="center")
# Define styles to a range
for row in sheet.iter_rows(min_row=1, max_row=3, min_col=1, max_col=3):
for cell in row:
cell.value = "hello"
cell.font = bold_red_font
cell.fill = yellow_fill
cell.border = thin_border
cell.alignment = center_alignment
workbook.save("range_styles.xlsx")
Last Updated at: 12/31/2025, 10:01:59 PM