使用openpyxl转换U列日期格式遇ValueError错误求助
嘿,我来帮你搞定这两个问题:样式重复的报错,以及带时区日期转成mm/dd/yy格式的需求。
首先,你遇到的ValueError: Style Normal exists already是因为NamedStyle默认会用"Normal"作为样式名——这可是Excel自带的内置样式,不能重复创建。所以第一个修复点就是给你的自定义样式起个独一无二的名字,比如"CustomMMDDYY"。
另外,你可能忽略了一个关键问题:你的原日期是带时区的字符串(比如2020-01-21 09:50:10.959355-05:00),如果单元格里存的是纯文本而不是Excel能识别的日期值,直接套样式根本不会生效。所以得先把这些字符串转换成日期时间对象,再设置格式。
下面给你两个最简方案,按需选择:
方案1:直接设置单元格数字格式(最省事)
跳过创建自定义样式的步骤,直接给单元格设置格式,同时完成文本到日期的转换:
from datetime import datetime import pytz # 处理时区,没装的话先跑 pip install pytz # 遍历U列(第21列) for row in sheet1.iter_rows(min_col=21, max_col=21, values_only=False): for cell in row: # 跳过空单元格 if not cell.value: continue # 解析带时区的日期字符串为datetime对象 dt = datetime.fromisoformat(cell.value) # (可选)如果需要转成UTC或本地时间,比如 dt = dt.astimezone(pytz.utc) # 将单元格值替换为datetime对象,让Excel识别为日期类型 cell.value = dt # 设置目标格式:mm/dd/yy cell.number_format = 'mm/dd/yy'
方案2:正确创建自定义样式(适合批量复用)
如果你确实想用样式统一管理格式,记得给样式指定唯一名称,避免和内置样式冲突:
from openpyxl.styles import NamedStyle from datetime import datetime import pytz # 创建自定义样式,指定唯一名称 date_style = NamedStyle(name="CustomMMDDYY", number_format='mm/dd/yy') # 先检查样式是否已存在,避免重复添加报错 if date_style.name not in sheet1.parent.style_names: sheet1.parent.add_named_style(date_style) # 遍历处理U列单元格 for row in sheet1.iter_rows(min_col=21, max_col=21, values_only=False): for cell in row: if not cell.value: continue dt = datetime.fromisoformat(cell.value) cell.value = dt cell.style = date_style
关于拆分空格的补充
完全没必要拆分日期和时间之间的空格!datetime.fromisoformat()可以直接解析YYYY-MM-DD HH:MM:SS.ffffff±HH:MM这种格式的字符串,直接转成datetime对象后,Excel就能识别为日期类型,设置格式后就能正常显示成你要的mm/dd/yy样式。
如果你的原数据已经是Excel的日期值(不是文本),那可以跳过转datetime的步骤,直接设置格式就行。但从你的描述来看,应该是文本格式的日期字符串,所以转换这一步必不可少。
内容的提问来源于stack exchange,提问作者ThisGuyUsesPowershell

