Skip to main content

openpyxl-toolkit

PyPI Python versions CI License

openpyxl formatting without the boilerplate.

Purpose

It is our opinion that formatting and styling worksheets with openpyxl is clunky and non-intuitive. We wanted to build something to make the process less painful and the end result more readable.

For example, openpyxl stores a cell's style as an immutable object. This means changing one attribute results in building an entirely new Font object and assigning it, which drops the size, the color, and anything else that was set:

>>> from copy import copy
>>> from openpyxl import Workbook
>>> from openpyxl.styles import Font

>>> wb = Workbook()
>>> ws = wb.active
>>> ws["A1"] = "My cell text"

>>> ws["A1"].font = Font(size=14, color="FF1D3557") # openpyxl wants ARGB
>>> ws["A1"].font = Font(bold=True) # the size and the color are now gone

If you try ws["A1"].font.bold = True, you get Style objects are immutable and cannot be changed. Reassign the style with a copy. So if you wanted to modify just one part of a font, you would have to make a copy, modify it, and assign it:

>>> font = copy(ws["A1"].font)
>>> font.bold = True
>>> ws["A1"].font = font

This toolkit allows you to change attributes one by one without having to copy previously set attributes.

>>> from openpyxl_toolkit import WorksheetToolkit

>>> toolkit = WorksheetToolkit(ws)
>>> toolkit.set_font(cells="A1", size=14, color="#1d3557")
>>> toolkit.set_font(cells="A1", bold=True) # size and color are not discarded

Install

pip install openpyxl-toolkit

Python 3.10 or newer, and openpyxl 3.1 or newer.

Methods

Cell formatting

Method What it sets
set_alignment horizontal, vertical, text_rotation, wrap_text, shrink_to_fit, indent, reading_order
set_border style and color, on any of six sides
set_outside_border one border around the edge of a block, leaving the inside alone
set_fill fill_type, start_color, end_color
set_font name, size, bold, italic, underline, strike, color
set_number_format how a value is displayed: currency, percent, dates, decimal places

Row and column formatting

Method What it sets
set_column_width / set_row_height an explicit size; 0 hides the column or row
set_column_best_fit a column width that fits the widest cell
merge_cells / unmerge_cells a merged range

Sheet-level controls

Method What it sets
freeze_panes rows above and columns left of a cell stay visible
set_autofilter Excel's filter controls on a range
set_gridline_visibility whether the grid between cells is drawn on screen
set_sheet_visibility whether the sheet is shown, hidden, or hidden from the unhide list too
set_tab_color the color of the sheet's tab
set_zoom_scale the zoom level when the reader opens the file: 10 to 400
>>> toolkit.set_tab_color("#1d3557")
>>> toolkit.set_gridline_visibility(visible=False)
>>> toolkit.set_autofilter(cells="A1:C3")
>>> toolkit.set_sheet_visibility(state="hidden")

Each method returns the toolkit, so calls can chain. Most parameters are keyword-only.

Anything not named is left as is. None is not the same as leaving out an argument: set_font(color=None) clears the color, while omitting color keeps whatever was there.

Cell selection

On every method that formats cells, there are 2 methods of selecting which cells the action should be applied to:

  1. cells
  2. rows and columns
>>> toolkit.set_fill(cells="A1:C3", fill_type="solid", start_color="#f4f6f8")
>>> toolkit.set_fill(cells="A:C", fill_type="solid", start_color="#f4f6f8")
>>> toolkit.set_fill(rows=[1, 2], columns=[1, 2], intersections_only=True,
...                  fill_type="solid", start_color="#ffff00")

cells takes a block ("A1:C3"), whole columns ("B:D"), whole rows ("2:5") or one cell ("C3"). Case does not matter, a reversed range such as "C3:A1" is normalized, and an unbounded side is filled in from the used range, so "B:B" means column B as far as the sheet goes (rather than all 1,048,576 rows).

rows and columns take lists. Leaving rows out (i.e., leaving it at the default of None) means every row is included. Leaving columns out means every column is included. An empty list for either means no cells will be selected.

Given both rows and columns, intersections_only decides what they mean:

Cells formatted
intersections_only=True (default) where the rows and the columns cross — a block
intersections_only=False every cell in those rows and every cell in those columns — a cross

Giving both cells and rows/columns raises.

Column letters and numbers

Because column letters can be hard to work with, we have provided a pair of functions for conversion. openpyxl has its own versions in openpyxl.utils, but under names that are more difficult to remember.

>>> from openpyxl_toolkit import column_letter, column_index

>>> column_letter(3)    # 'C'
>>> column_index("C")   # 3
>>> toolkit.set_column_width(width=18, columns=[column_index("D")])

Type hints

The package ships py.typed. Alignment names, border styles, fill patterns and underline styles are Literal types, so an editor completes them and a checker catches a typo before the code runs:

error: Argument "horizontal" to "set_alignment" has incompatible type "Literal['centre']"

openpyxl rejects the same typo, but only once the call runs; the Literal types move it into the editor. Elsewhere the annotations really are stricter than openpyxl is at runtime, which matters more than it sounds: openpyxl accepts bold="no" and stores True, and name=42 and stores "42".

License

MIT.

Metadata

Release files for openpyxl-toolkit 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for openpyxl-toolkit 0.5.0
File Size Uploaded
openpyxl_toolkit-0.5.0.tar.gz 72.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for openpyxl-toolkit 0.5.0
File Interpreter ABI Platform
openpyxl_toolkit-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 111.0 kB

Release files / openpyxl_toolkit-0.5.0.tar.gz

Download URL openpyxl_toolkit-0.5.0.tar.gz
Size 72.9 kB
Tags Source
SHA-256 checksum
How to use checksums
6ce5f1d1b3a7c2b75852f0e02943f7b737eebc451cbf8bd9f6c2347ed9013a3d
BLAKE2b-256 checksum
How to use checksums
1186b73e1ac1582538edcf9c755670e8776c8f7e4150dda6ced70d69e45b581c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / openpyxl_toolkit-0.5.0-py3-none-any.whl

Download URL openpyxl_toolkit-0.5.0-py3-none-any.whl
Size 38.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
46d5566061d9f4ef578b1e8567609ca86e0f558d35ac0c2bc589508973abe055
BLAKE2b-256 checksum
How to use checksums
08ed9150012743a8786abc7261bf139fd7be1ac2c2b13c5f8cd9e53926e96e84
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page