常见原因是直接将字典、none或嵌套列表赋值给cell.value,而openpyxl仅接受str、int、float、bool、datetime或none等基础类型;错误写法如ws['a1'].value = {'name': '张三'}会导致单元格显示0,正确做法是拆解字段逐个赋值。

openpyxl写入数据时为什么单元格显示为0或空白?
常见原因是直接把字典、None或嵌套列表整体赋值给cell.value,而openpyxl不自动展开或转换类型。它只接受基础Python类型(str、int、float、bool、datetime)或空值None。
- 错误写法:
ws['A1'].value = {'name': '张三', 'age': 25}→ 单元格显示0 - 正确做法:拆解字段,逐字段赋值,如
ws['A1'].value = item['name']、ws['B1'].value = item['age'] - 若数据含
None,可预处理:str(item.get('remark', ''))避免写入None导致格式异常 - 注意:
ws.append()接受列表,但列表内每个元素仍需是基础类型;传入字典会静默失败
如何用openpyxl设置表头样式和自动列宽?
openpyxl默认无样式、无自适应列宽,需手动设置,否则导出的Excel看起来像原始数据表,不易阅读。
- 设置表头字体加粗居中:
from openpyxl.styles import Font, Alignment,然后对第一行单元格批量设置font=Font(bold=True)和alignment=Alignment(horizontal='center') - 自动列宽推荐逻辑:遍历每列所有非空单元格,取
len(str(cell.value))最大值,再加2缓冲,最后用ws.column_dimensions[col_letter].width = width赋值 - 注意:列宽单位不是像素,且中文字符宽度≈2个英文字符,简单按字符串长度算可能偏窄;实际可用
min(max_len * 1.2, 50)做上限限制 - 别忘了冻结首行:
ws.freeze_panes = 'A2',方便滚动查看
爬虫数据含URL、日期、数字时如何保持Excel原生格式?
直接写字符串会让Excel识别失败——比如'2024-03-15'被当文本而非日期,'https://example.com'无法点击跳转,数字带千分位或小数位丢失。
- 日期字段:确保原始数据是
datetime.date或datetime.datetime对象,直接赋值即可,openpyxl会自动映射为Excel日期格式;若为字符串,先用datetime.strptime()解析 - 超链接:用
cell.hyperlink = url+cell.style = 'Hyperlink',不能只写字符串 - 数字格式:用
cell.number_format控制显示,例如金额用'¥#,##0.00',百分比用'0.00%';注意这仅影响显示,不影响底层数值 - 避免用
str()包裹数字/日期后再写入,否则彻底失去格式能力
保存大文件时内存暴涨或卡死怎么办?
openpyxl是内存式操作,全量加载工作簿到对象中。抓取上万条数据时,未优化易触发OOM或保存超时。
- 优先用
write_only=True创建工作簿:Workbook(write_only=True),此时只能顺序写入,但内存占用极低 - 禁用样式(如不需要表头加粗)可显著提速;样式越多,内存开销越大
- 避免在循环中反复调用
ws.cell(row=i, column=j),改用ws.append(row_list)批量写入整行 - 写完后务必调用
wb.close(),否则文件句柄未释放,后续读取可能报错PermissionError
真正麻烦的不是写入本身,而是混合了样式、超链接、合并单元格之后的格式校验——这些操作一旦加在万行数据上,性能断崖式下降,建议只在必要字段上启用。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











