1. 项目背景与核心需求
在日常数据处理工作中,我们经常需要将数据库中的信息导出到Excel进行二次处理或分享。最近接手了一个客户项目,需要每周从SQLite数据库导出近万条销售记录到Excel文件,手动操作不仅效率低下还容易出错。于是用Python写了个自动化脚本,现在把完整实现方案分享给大家。
这个方案的核心价值在于:
- 支持批量导出多个表或查询结果
- 自动处理数据类型转换
- 可定制导出字段和格式
- 异常情况自动重试机制
- 生成带格式的Excel文件
2. 技术方案选型
2.1 数据库连接方案
对于SQLite数据库,Python标准库中的sqlite3模块是最佳选择:
python复制import sqlite3
conn = sqlite3.connect('sales.db')
如果连接其他数据库,推荐使用:
- MySQL:PyMySQL或mysql-connector
- PostgreSQL:psycopg2
- Oracle:cx_Oracle
提示:生产环境建议使用连接池,如DBUtils包
2.2 Excel操作库对比
测试了三个主流库的性能(导出10000行数据):
| 库名称 | 写入速度 | 功能丰富度 | 内存占用 | 文件格式支持 |
|---|---|---|---|---|
| xlwt | 快 | 一般 | 低 | 仅xls |
| openpyxl | 中等 | 丰富 | 高 | xlsx |
| pandas | 最快 | 专业 | 中等 | 多格式 |
最终选择pandas,因为:
- 内置数据库连接支持
- 自动处理数据类型转换
- 支持导出多种格式(xlsx/csv等)
- 可以轻松添加样式和公式
3. 完整实现代码
3.1 基础导出功能
python复制import sqlite3
import pandas as pd
def export_to_excel(db_path, table_name, output_file):
"""基础导出单表到Excel"""
conn = sqlite3.connect(db_path)
df = pd.read_sql(f"SELECT * FROM {table_name}", conn)
df.to_excel(output_file, index=False)
conn.close()
3.2 增强版导出功能
python复制def batch_export(db_path, queries, output_file, styles=None):
"""
批量导出增强版
:param db_path: 数据库路径
:param queries: 查询字典 {'sheet名': 'SQL查询'}
:param output_file: 输出文件路径
:param styles: 格式字典 {'列名': 格式}
"""
conn = sqlite3.connect(db_path)
writer = pd.ExcelWriter(output_file, engine='xlsxwriter')
for sheet_name, query in queries.items():
df = pd.read_sql(query, conn)
df.to_excel(writer, sheet_name=sheet_name, index=False)
if styles:
workbook = writer.book
worksheet = writer.sheets[sheet_name]
for col, style in styles.items():
if col in df.columns:
col_idx = df.columns.get_loc(col)
fmt = workbook.add_format(style)
worksheet.set_column(col_idx, col_idx, None, fmt)
writer.close()
conn.close()
4. 实战应用示例
4.1 导出销售数据
python复制queries = {
'销售汇总': 'SELECT date, product, SUM(amount) as total FROM sales GROUP BY date, product',
'客户排名': 'SELECT customer, SUM(amount) as total FROM sales GROUP BY customer ORDER BY total DESC'
}
styles = {
'total': {'num_format': '#,##0.00', 'bold': True},
'date': {'num_format': 'yyyy-mm-dd'}
}
batch_export('sales.db', queries, 'sales_report.xlsx', styles)
4.2 定时自动导出
结合Windows任务计划或Linux cron实现每天自动导出:
python复制import schedule
import time
def daily_export():
batch_export(...) # 填入实际参数
schedule.every().day.at("08:00").do(daily_export)
while True:
schedule.run_pending()
time.sleep(60)
5. 性能优化技巧
处理大数据量时(10万行以上):
- 分块读取数据:
python复制chunksize = 10000
for chunk in pd.read_sql_query(query, conn, chunksize=chunksize):
process(chunk)
- 禁用索引自动创建:
python复制df.to_excel(..., index=False)
- 使用临时文件:
python复制with tempfile.NamedTemporaryFile() as tmp:
df.to_excel(tmp.name)
# 处理临时文件
6. 常见问题解决方案
6.1 中文乱码问题
解决方法:
python复制df = pd.read_sql(query, conn)
df = df.apply(lambda x: x.str.decode('utf-8') if x.dtype == object else x)
6.2 日期格式异常
强制转换日期列:
python复制df['date_column'] = pd.to_datetime(df['date_column'], errors='coerce')
6.3 内存不足处理
使用低内存模式:
python复制pd.read_sql(query, conn, dtype={
'text_col': 'string',
'num_col': 'float32'
})
7. 扩展功能实现
7.1 添加数据透视表
python复制pivot = df.pivot_table(index='date', columns='product', values='amount')
pivot.to_excel(writer, sheet_name='透视表')
7.2 生成图表
python复制chart = workbook.add_chart({'type': 'column'})
chart.add_series({'values': '=透视表!$B$2:$B$10'})
worksheet.insert_chart('D2', chart)
7.3 自动发送邮件
python复制import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
msg = MIMEMultipart()
msg['Subject'] = '每日销售报告'
msg.attach(MIMEBase('application', 'octet-stream'))
with open('sales_report.xlsx', 'rb') as f:
msg.attach(f.read())
smtp = smtplib.SMTP('smtp.example.com')
smtp.sendmail('from@example.com', 'to@example.com', msg.as_string())
8. 项目部署建议
-
生产环境建议添加以下功能:
- 导出前数据校验
- 失败自动重试机制
- 导出完成通知
- 日志记录
-
对于敏感数据,建议添加:
- 自动加密功能
- 密码保护Excel文件
- 访问权限控制
-
性能监控指标:
- 导出耗时
- 内存峰值
- 记录处理行数
这个方案在我们生产环境稳定运行了6个月,每天处理超过5万条记录。最大的收获是一定要做好异常处理,特别是数据库连接超时和磁盘空间不足的情况。建议添加自动清理旧文件的逻辑,避免磁盘被撑爆
