如何使用Python和Openpyxl将MySQL查询结果导出为Excel报表?

陌枫吖_7510

陌枫吖_7510

2026-08-25

315人浏览

原创

不能用append()循环写万行数据,因每次调用均重建单元格对象、刷新样式缓存,致耗时超2分钟、内存飙升至500mb+;应一次性转二维列表或dataframe后单次append,或用cell()直接赋值。

如何使用python和openpyxl将mysql查询结果导出为excel报表?

能导出,但别直接用 openpyxl 一行行写数据——性能差、易出错、内存爆掉是常态。

为什么不能用 append() 循环写万行数据?

常见错误是查完 MySQL 结果集后,对每行调一次 ws.append(row)。这看似简单,实际会触发 openpyxl 每次都重建单元格对象、反复刷新样式缓存,1 万行耗时可能超 2 分钟,内存占用飙升到 500MB+。

真正该做的是:一次性把数据转成二维列表或 pandas.DataFrame,再用 ws.append() 批量写入(只调一次),或者更优——用 ws.cell() 直接定位赋值。

  • cursor.fetchall() 返回的是 tuple 元组列表,需转成 list 或保持原样传给 append()(它支持 tuple)
  • 如果字段含 datetime、Decimal、None,openpyxl 默认不识别,得提前转成 str 或 float;否则报 ValueError: Cannot convert <class> to Excel</class>
  • 别在循环里调 wb.save(),必须全部写完再保存一次

如何安全处理 MySQL 的 NULL、datetime 和 Decimal 字段?

MySQL 驱动(如 pymysql 或 mysql-connector-python)返回的 None、datetime.datetime、decimal.Decimal 不能直接塞进 Excel 单元格。

最稳妥的做法是在写入前统一清洗:

excel-toolkit
excel-toolkit

创建、检查和编辑 Microsoft Excel 工作簿及 XLSX 文件,具备可靠的公式、日期、类型、格式、重新计算和模板保留功能...

下载
  • 用 row = [v if v is not None else "" for v in row] 处理 NULL
  • 对 datetime 类型字段,用 v.strftime("%Y-%m-%d %H:%M:%S") 转字符串(或保留为 datetime 对象,openpyxl 支持,但 Excel 单元格格式需手动设为日期)
  • 对 Decimal,用 float(v) 或 str(v) ——选 float 更利于后续 Excel 公式计算

示例清洗逻辑:

def clean_row(row):
    return [
        "" if v is None else
        v.strftime("%Y-%m-%d %H:%M:%S") if hasattr(v, "strftime") else
        float(v) if hasattr(v, "as_tuple") else  # decimal.Decimal
        v
        for v in row
    ]

怎么让表头自动加粗、冻结首行、列宽自适应?

openpyxl 不会自动美化,但几行代码就能搞定基础排版:

  • 表头加粗:for cell in ws[1]: cell.font = Font(bold=True)
  • 冻结首行:ws.freeze_panes = "A2"
  • 列宽自适应(注意:不能真“自适应”,只能按字符数估算):for column_cells in ws.columns: length = max(len(str(cell.value)) for cell in column_cells); ws.column_dimensions[column_cells[0].column_letter].width = min(length + 2, 50)

别用 ws.auto_filter 自动加筛选器——它只对连续非空区域生效,且必须在写完所有数据后设置:ws.auto_filter.ref = ws.dimensions(但要确保第一行是纯表头、无合并单元格)

导出大表(>10 万行)的替代方案

openpyxl 在百万行级场景下会卡死或 OOM。这时候别硬扛:

  • 改用 xlsxwriter:它流式写入、内存友好,但不支持读取已有文件
  • 分页导出:用 LIMIT + OFFSET 分批查,每批 5 万行,生成多个 sheet 或多个文件
  • 跳过 Excel,导出 CSV:用 csv.writer 写文件,再用 Excel 打开(兼容性好、速度快、无内存压力)

真正麻烦的不是“怎么导出”,而是“导出后用户要不要在 Excel 里做公式、透视、筛选”——如果要,就得保格式、保类型、保冻结;如果只是看数,CSV 真的够用。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1631

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

3984

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1629

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

22997

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2827

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2867

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1123

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2223

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 178人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 282人学习