openpyxl ValueError: Cannot convert to Excel (tested)

openpyxl raises ValueError: Cannot convert [1, 2] to Excel when a cell is given something that isn't a single number, string, bool or date: a list, dict, NumPy array or UUID. Timezone-aware datetimes are different: they are accepted, then fail with a TypeError at save().

1. Which values openpyxl refuses

import datetime as dt, decimal, uuid
import numpy as np
from openpyxl import Workbook
ws = Workbook().active
values = {
    "list": [1, 2], "dict": {"a": 1}, "tuple": (1, 2), "set": {1},
    "uuid": uuid.uuid4(), "numpy float64": np.float64(1.5), "numpy int64": np.int64(3),
    "numpy array": np.array([1, 2]), "Decimal": decimal.Decimal("1.10"),
    "tz-aware datetime": dt.datetime(2026, 10, 23, 6, 0, tzinfo=dt.timezone.utc),
}
for name, v in values.items():
    try:
        ws["A1"] = v
        print(f"{name:18} ok -> stored {ws['A1'].value!r}")
    except Exception as e:
        print(f"{name:18} {type(e).__name__}: {e}")

Output:

list               ValueError: Cannot convert [1, 2] to Excel
dict               ValueError: Cannot convert {'a': 1} to Excel
tuple              ValueError: Cannot convert (1, 2) to Excel
set                ValueError: Cannot convert {1} to Excel
uuid               ValueError: Cannot convert UUID('e3b3233f-93e6-4359-bd00-ab65b1947cb1') to Excel
numpy float64      ok -> stored np.float64(1.5)
numpy int64        ok -> stored np.int64(3)
numpy array        ValueError: Cannot convert array([1, 2]) to Excel
Decimal            ok -> stored Decimal('1.10')
tz-aware datetime  ok -> stored datetime.datetime(2026, 10, 23, 6, 0, tzinfo=datetime.timezone.utc)

A cell holds one scalar: a number, string, bool, date/time or None. Containers (list, tuple, dict, set, NumPy arrays) and arbitrary objects such as UUID raise ValueError: Cannot convert ... to Excel at assignment (or on ws.append), and the message prints the offending value, which is your best clue to which column it came from. NumPy scalars and Decimal are accepted.

Fix it by converting before writing: ", ".join(tags) or json.dumps(obj) for containers, str(u) for UUIDs. If the value came out of a DataFrame, look for an object column holding lists, e.g. after a groupby().agg(list) or a JSON column.

2. Timezones: accepted at assignment, rejected at save

import datetime as dt, io
from openpyxl import Workbook, load_workbook
wb = Workbook(); ws = wb.active
ws["A1"] = dt.datetime(2026, 10, 23, 6, 0, tzinfo=dt.timezone(dt.timedelta(hours=2)))
buf = io.BytesIO()
try:
    wb.save(buf)
    print("saved; read back:", repr(load_workbook(buf).active["A1"].value))
except Exception as e:
    print(type(e).__name__, e)

Output:

TypeError Excel does not support timezones in datetimes. The tzinfo in the datetime/time object must be set to None.

The timezone-aware datetime in block 1 was stored without complaint. The error only appears at wb.save(), as a TypeError, not a ValueError, so a try/except around the cell assignment never sees it. Excel has no timezone concept: convert to the zone you want shown, then drop the tzinfo, e.g. d.astimezone(dt.timezone.utc).replace(tzinfo=None).

3. The same errors from pandas to_excel

import io
import pandas as pd
df = pd.DataFrame({"when": pd.to_datetime(["2026-10-23 06:00"]).tz_localize("UTC"),
                   "tags": [["a", "b"]]})
try:
    df.to_excel(io.BytesIO(), index=False)
except Exception as e:
    print(type(e).__name__, e)
df["when"] = df["when"].dt.tz_localize(None)       # drop tz, keep UTC wall time
df["tags"] = df["tags"].map(", ".join)             # list -> text
df.to_excel(io.BytesIO(), index=False)
print("written after fix:", df.to_dict("records"))

Output:

ValueError Excel does not support datetimes with timezones. Please ensure that datetimes are timezone unaware before writing to Excel.
written after fix: [{'when': Timestamp('2026-10-23 06:00:00'), 'tags': 'a, b'}]

DataFrame.to_excel checks timezones itself and raises its own ValueError ("Excel does not support datetimes with timezones"). Strip the zone with .dt.tz_localize(None) (keeps the wall-clock time) or .dt.tz_convert("Europe/Paris").dt.tz_localize(None) to show local time, and flatten list columns to text.

Checklist

Related: openpyxl IllegalCharacterError, openpyxl InvalidFileException.

Frequently asked questions

What does Cannot convert to Excel mean in openpyxl?

A cell was given a value openpyxl can't store, such as a list, dict, set, NumPy array or UUID. Convert it to a string or number first.

How do I fix Excel does not support timezones in datetimes?

Remove tzinfo before saving: d.replace(tzinfo=None) after converting to the zone you want, or df['col'].dt.tz_localize(None) in pandas.

Can openpyxl write numpy values?

Yes. In openpyxl 3.1.5 NumPy scalars like np.float64 and np.int64 are accepted; whole NumPy arrays are not.

Written with AI assistance. Measured on 2026-10-23 with openpyxl 3.1.5, pandas 3.1.0, NumPy 2.5.4 and Python 3.14.7 (python:3-alpine in Docker). Each block was run verbatim and the output pasted unedited (the UUID is random per run). PlainTables is our extension; Python and openpyxl are free.