Python 自动化 Excel 写入数据(列表、字典、数据库数据直接写入)详细教程
在Python自动化办公场景中,写入Excel是最常用的功能之一。无论是写入手动整理的数据、程序生成的计算结果,还是从数据库查询的数据,Python都能轻松实现。本文将详细介绍三种常见的数据写入方式,包含完整代码示例和最佳实践。
一、环境准备
1.1 安装依赖库
# 基础库
pip install openpyxl pandas
# 如果需要连接数据库,安装对应的驱动
pip install pymysql # MySQL驱动
pip install psycopg2-binary # PostgreSQL驱动
pip install sqlalchemy # ORM框架,支持多种数据库
1.2 库选择建议
| 库 | 优势 | 适用场景 |
|—–|——|———-|
| openpyxl | 支持精细控制,格式设置灵活 | 需要设置单元格样式、公式、图表等场景 |
| pandas | 接口简单,批量写入速度快 | 结构化数据批量写入,不需要复杂格式 |
| xlsxwriter | 格式支持丰富,性能高 | 大量数据写入,需要复杂格式 |
> 💡 新手建议:大部分场景用pandas最简单,需要精细格式控制再用openpyxl。
二、写入列表数据
列表是最常见的数据结构,适合写入结构化的表格数据。
2.1 使用pandas写入列表数据
import pandas as pd
# 示例数据:列表嵌套列表,第一行是表头
data = [
["姓名", "部门", "入职日期", "工资", "绩效"],
["张三", "技术部", "2023-05-15", 15000, "A"],
["李四", "产品部", "2024-02-20", 12000, "B"],
["王五", "销售部", "2022-11-08", 18000, "A"],
["赵六", "人事部", "2023-08-10", 10000, "B"]
]
# 转换为DataFrame,第一行作为表头
df = pd.DataFrame(data[1:], columns=data[0])
# 写入Excel
df.to_excel("员工信息.xlsx", index=False, sheet_name="员工表")
print("✅ 列表数据写入成功!")
2.2 使用openpyxl写入列表数据
需要更精细控制时用openpyxl:
from openpyxl import Workbook
from openpyxl.utils import get_column_letter
from openpyxl.styles import Font, PatternFill, Alignment
wb = Workbook()
ws = wb.active
ws.title = "员工表"
data = [
["姓名", "部门", "入职日期", "工资", "绩效"],
["张三", "技术部", "2023-05-15", 15000, "A"],
["李四", "产品部", "2024-02-20", 12000, "B"],
["王五", "销售部", "2022-11-08", 18000, "A"],
["赵六", "人事部", "2023-08-10", 10000, "B"]
]
# 设置表头样式
header_font = Font(bold=True, color="FFFFFF")
header_fill = PatternFill(start_color="3498db", end_color="3498db", fill_type="solid")
header_alignment = Alignment(horizontal="center")
# 写入数据
for row_idx, row_data in enumerate(data, 1):
for col_idx, value in enumerate(row_data, 1):
cell = ws.cell(row=row_idx, column=col_idx, value=value)
# 表头应用样式
if row_idx == 1:
cell.font = header_font
cell.fill = header_fill
cell.alignment = header_alignment
# 调整列宽
for col in range(1, len(data[0]) + 1):
ws.column_dimensions[get_column_letter(col)].width = 15
# 保存文件
wb.save("员工信息_openpyxl.xlsx")
print("✅ 列表数据写入成功(带样式)!")
2.3 写入大列表优化
当数据量很大(超过10万行)时,使用openpyxl的只写模式提升性能:
from openpyxl import Workbook
# 开启只写模式,写入速度提升10倍以上
wb = Workbook(write_only=True)
ws = wb.create_sheet("大数据表")
# 生成10万行测试数据
header = ["序号", "数值1", "数值2", "数值3", "计算结果"]
ws.append(header)
for i in range(100000):
row = [i+1, i*2, i*3, i*4, i*9]
ws.append(row)
wb.save("大数据表.xlsx")
print("✅ 10万行数据写入成功!")
> ⚠️ 注意:只写模式下不能读取或修改已写入的数据,适合一次性写入大量数据的场景。
三、写入字典数据
字典数据结构更灵活,适合key-value类型的数据写入。
3.1 字典列表写入
最常见的是字典列表,每个字典代表一行数据:
import pandas as pd
data = [
{"姓名": "张三", "部门": "技术部", "入职日期": "2023-05-15", "工资": 15000, "绩效": "A"},
{"姓名": "李四", "部门": "产品部", "入职日期": "2024-02-20", "工资": 12000, "绩效": "B"},
{"姓名": "王五", "部门": "销售部", "入职日期": "2022-11-08", "工资": 18000, "绩效": "A"},
{"姓名": "赵六", "部门": "人事部", "入职日期": "2023-08-10", "工资": 10000, "绩效": "B"}
]
# 直接转换为DataFrame,字典的key自动作为表头
df = pd.DataFrame(data)
# 可以指定列的顺序
df = df[["姓名", "部门", "入职日期", "工资", "绩效"]]
df.to_excel("员工信息_字典.xlsx", index=False)
print("✅ 字典列表写入成功!")
3.2 单个字典写入(横向)
有时候需要把单个字典横向写入一行:
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
data = {
"公司名称": "XX科技有限公司",
"报表日期": "2026-03-31",
"员工总数": 128,
"本月销售额": 5680000,
"利润率": 0.32
}
# 写入字典,每个key-value占一列
for col_idx, (key, value) in enumerate(data.items(), 1):
ws.cell(row=1, column=col_idx*2-1, value=key)
ws.cell(row=1, column=col_idx*2, value=value)
# 调整列宽
for col in range(1, len(data)*2 + 1):
ws.column_dimensions[chr(64 + col)].width = 15
wb.save("公司信息.xlsx")
print("✅ 单个字典写入成功!")
3.3 嵌套字典写入
处理嵌套字典结构,比如二级表头:
import pandas as pd
from collections import defaultdict
# 嵌套字典示例:按部门分组的员工数据
data = {
"技术部": {
"张三": {"工资": 15000, "绩效": "A", "入职年限": 3},
"王五": {"工资": 18000, "绩效": "A", "入职年限": 4}
},
"产品部": {
"李四": {"工资": 12000, "绩效": "B", "入职年限": 2}
}
}
# 转换为扁平结构
flat_data = []
for dept, employees in data.items():
for name, info in employees.items():
row = {"部门": dept, "姓名": name}
row.update(info)
flat_data.append(row)
df = pd.DataFrame(flat_data)
df.to_excel("部门员工信息.xlsx", index=False)
print("✅ 嵌套字典写入成功!")
四、写入数据库查询结果
实际工作中,经常需要把数据库查询结果直接导出到Excel。
4.1 使用pandas + SQLAlchemy(推荐)
SQLAlchemy支持几乎所有主流数据库,写法统一:
import pandas as pd
from sqlalchemy import create_engine
# 1. 创建数据库连接(以MySQL为例)
# 连接格式:数据库类型+驱动://用户名:密码@主机:端口/数据库名
engine = create_engine("mysql+pymysql://user:password@localhost:3306/company_db?charset=utf8mb4")
# 2. 执行SQL查询
sql = """
SELECT
e.id,
e.name,
d.dept_name,
e.hire_date,
e.salary,
e.performance
FROM
employee e
LEFT JOIN
department d ON e.dept_id = d.id
WHERE
e.status = 1
"""
# 3. 直接读取查询结果到DataFrame
df = pd.read_sql(sql, engine)
# 4. 写入Excel
df.to_excel("员工数据库导出.xlsx", index=False, sheet_name="员工数据")
print("✅ 数据库查询结果写入成功!")
4.2 不同数据库连接示例
MySQL
engine = create_engine("mysql+pymysql://user:password@localhost:3306/db_name?charset=utf8mb4")
PostgreSQL
engine = create_engine("postgresql+psycopg2://user:password@localhost:5432/db_name")
SQLite
engine = create_engine("sqlite:///database.db")
SQL Server
engine = create_engine("mssql+pyodbc://user:password@dsn_name")
4.3 使用原生数据库驱动
如果不想用SQLAlchemy,可以用原生驱动:
import pymysql
import pandas as pd
# 连接数据库
conn = pymysql.connect(
host="localhost",
user="user",
password="password",
database="company_db",
charset="utf8mb4"
)
# 执行查询
sql = "SELECT * FROM employee WHERE status = 1"
df = pd.read_sql(sql, conn)
# 写入Excel
df.to_excel("员工数据_原生驱动.xlsx", index=False)
# 关闭连接
conn.close()
print("✅ 数据库查询结果写入成功(原生驱动)!")
4.4 分批写入大数据量
当查询结果太大(超过100万行)时,分批读取写入:
import pandas as pd
from sqlalchemy import create_engine
engine = create_engine("mysql+pymysql://user:password@localhost:3306/company_db")
# 每次读取10万行
chunksize = 100000
sql = "SELECT * FROM big_table"
# 创建Excel写入器
with pd.ExcelWriter("大数据导出.xlsx", engine="openpyxl") as writer:
startrow = 0
for i, chunk in enumerate(pd.read_sql(sql, engine, chunksize=chunksize)):
# 第一个chunk写入表头,后续不写表头
chunk.to_excel(writer, index=False, sheet_name="数据", header=(i==0), startrow=startrow)
startrow += len(chunk)
print(f"✅ 已写入 {startrow} 行")
print("✅ 大数据分批写入完成!")
五、高级写入技巧
5.1 写入不同工作表
一个Excel文件写入多个工作表:
import pandas as pd
# 准备不同的数据
df1 = pd.DataFrame({"姓名": ["张三", "李四", "王五"], "工资": [15000, 12000, 18000]})
df2 = pd.DataFrame({"部门": ["技术部", "产品部", "销售部"], "人数": [20, 10, 30]})
df3 = pd.DataFrame({"月份": ["1月", "2月", "3月"], "销售额": [1200000, 1500000, 1800000]})
# 创建写入器
with pd.ExcelWriter("多工作表.xlsx") as writer:
df1.to_excel(writer, sheet_name="员工工资", index=False)
df2.to_excel(writer, sheet_name="部门统计", index=False)
df3.to_excel(writer, sheet_name="销售数据", index=False)
print("✅ 多工作表写入成功!")
5.2 追加数据到已有Excel
在已有的Excel文件后面追加数据:
import pandas as pd
from openpyxl import load_workbook
# 已有文件路径
file_path = "员工信息.xlsx"
# 新数据
new_data = pd.DataFrame({
"姓名": ["孙七", "周八"],
"部门": ["市场部", "财务部"],
"入职日期": ["2024-01-15", "2023-11-20"],
"工资": [11000, 13000],
"绩效": ["B", "A"]
})
# 读取已有文件,获取现有行数
book = load_workbook(file_path)
writer = pd.ExcelWriter(file_path, engine="openpyxl", mode="a", if_sheet_exists="overlay")
writer.book = book
writer.sheets = {ws.title: ws for ws in book.worksheets}
# 追加数据,不写表头,从最后一行开始
startrow = writer.sheets["员工表"].max_row
new_data.to_excel(writer, sheet_name="员工表", index=False, header=False, startrow=startrow)
writer.close()
print("✅ 数据追加成功!")
5.3 写入时设置数据格式
设置列的格式,比如日期、货币、百分比:
import pandas as pd
from openpyxl import load_workbook
from openpyxl.styles import numbers
# 准备数据
data = [
["姓名", "入职日期", "工资", "绩效", "完成率"],
["张三", "2023-05-15", 15000, "A", 0.95],
["李四", "2024-02-20", 12000, "B", 0.88],
["王五", "2022-11-08", 18000, "A", 0.98]
]
df = pd.DataFrame(data[1:], columns=data[0])
df.to_excel("带格式的数据.xlsx", index=False)
# 打开文件设置格式
wb = load_workbook("带格式的数据.xlsx")
ws = wb.active
# 设置列格式
for row in range(2, ws.max_row + 1):
# 入职日期列(B列)设置日期格式
ws[f"B{row}"].number_format = "YYYY-MM-DD"
# 工资列(C列)设置货币格式
ws[f"C{row}"].number_format = "¥#,##0"
# 完成率列(E列)设置百分比格式
ws[f"E{row}"].number_format = "0.0%"
wb.save("带格式的数据.xlsx")
print("✅ 带格式数据写入成功!")
5.4 写入公式
在Excel中写入计算公式,打开文件时自动计算:
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
# 写入表头
ws.append(["商品名称", "成本价", "售价", "销量", "利润"])
# 写入数据
data = [
["商品A", 80, 120, 100],
["商品B", 60, 90, 150],
["商品C", 100, 150, 80]
]
for row in data:
ws.append(row)
# 写入利润计算公式:利润 = (售价 - 成本价) * 销量
for row in range(2, len(data) + 2):
ws[f"E{row}"] = f"=(C{row}-B{row})*D{row}"
# 写入合计
ws.append(["合计", "", "", f"=SUM(D2:D{len(data)+1})", f"=SUM(E2:E{len(data)+1})"])
wb.save("带公式的表格.xlsx")
print("✅ 带公式的表格写入成功!")
六、常见问题与解决方案
6.1 中文乱码问题
问题:写入Excel后中文显示乱码
解决方案:
df.to_excel("文件.xlsx", index=False, encoding="utf-8")
# MySQL连接加charset=utf8mb4
engine = create_engine("mysql+pymysql://user:password@localhost:3306/db_name?charset=utf8mb4")
6.2 写入速度慢问题
问题:写入大量数据时速度很慢
解决方案:
6.3 数据类型错误问题
问题:数字变成字符串,日期格式不对
解决方案:
# 转换日期列
df['入职日期'] = pd.to_datetime(df['入职日期'])
# 转换数字列
df['工资'] = pd.to_numeric(df['工资'], errors='coerce')
6.4 内存不足问题
问题:写入几十万行数据时内存不足
解决方案:
6.5 文件被占用问题
问题:保存文件时提示权限错误
解决方案:
七、最佳实践
1. 优先用pandas:简单快速,90%的场景都能满足
2. 数据类型提前转换:写入前处理好数据类型,避免写入后格式错误
3. 大文件分批处理:超过10万行数据分批写入,避免内存溢出
4. 异常处理:文件操作时加try-except,处理文件占用、权限不足等问题
5. 及时保存:写入过程中定期保存,避免程序崩溃丢失数据
6. 命名规范:文件名包含日期、版本号,避免覆盖重要文件
通过以上方法,你可以轻松实现各种场景下的Excel数据写入,不管是简单的列表还是复杂的数据库查询结果,都能快速导出到Excel文件,大幅提升办公效率。