
mysql命令行直接导出CSV(不是Excel)
MySQL本身不生成.xlsx文件,最可靠、零依赖的方式是导出为CSV,再用Excel打开。别被“导出Excel”误导——真正落地时,SELECT ... INTO OUTFILE或mysqldump --tab输出的都是纯文本CSV/TSV。
-
INTO OUTFILE只能写入数据库服务器本地磁盘,且要求secure_file_priv路径放开,普通用户常卡在这儿 - 客户端导出(如
mysql -e "SELECT ..." > data.csv)更灵活,但默认用制表符分隔,需加--batch和--raw并手动处理引号和换行 - 中文字段必须指定
CHARACTER SET utf8mb4,否则Excel打开乱码;推荐在连接时加--default-character-set=utf8mb4
用SELECT ... INTO OUTFILE生成带标题的CSV
这个语句本身不生成列名行,硬加标题得拼接:UNION ALL + SELECT字符串字面量。但要注意类型对齐和NULL处理,否则报错Column count doesn't match value count。
- 所有字段必须显式转成字符串,比如
CAST(id AS CHAR)或CONCAT('', id) - 标题行字段数必须和数据行完全一致,少一个就失败
- 导出路径由
secure_file_priv变量决定,执行SHOW VARIABLES LIKE 'secure_file_priv';先确认可写目录 - 示例:
SELECT 'id','name','created_at' UNION ALL SELECT CAST(id AS CHAR), name, created_at FROM users INTO OUTFILE '/var/lib/mysql-files/users.csv' CHARACTER SET utf8mb4 FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';
Python脚本补位:pandas读取SQL结果写Excel
当必须输出.xlsx(含样式、多Sheet、公式),绕不开应用层处理。pandas + openpyxl是最稳组合,比PHP/Java轻量,也避开了JDBC驱动兼容问题。
- 别用
mysql-connector-python的cursor.fetchall()直接喂给pd.DataFrame——日期、JSON字段会变成bytes或None,优先用sqlalchemy引擎+pd.read_sql -
to_excel默认不写索引,但若忘了index=False,第一列会多出无意义的数字序号 - 大数据量(>10万行)别一次性
read_sql,用chunksize分批写入,否则内存爆掉 - 示例关键行:
df = pd.read_sql("SELECT * FROM orders WHERE status='done'", engine)df.to_excel("orders.xlsx", index=False)
Navicat / DBeaver等GUI工具的导出陷阱
这些工具点几下就能“导出Excel”,但背后行为差异大,容易误判结果正确性。
- Navicat默认用
INSERT语句导出为.sql,选“Excel”格式才走CSV流程;务必检查导出设置里的“字段分隔符”和“文本标识符”,逗号+双引号是Excel友好组合 - DBeaver导出CSV时若勾了“Use native client export”,实际调的是
mysqldump --tab,仍受限于secure_file_priv,不是真从客户端机器写文件 - 所有GUI工具导出含NULL值的字段时,默认显示为空白,但Excel里它可能是空字符串
""而非真正NULL,做数据校验时得用IS NULL查,不能只看是否为空
真正麻烦的从来不是“怎么导出”,而是导出后Excel自动把手机号当数字、把以0开头的编码截断、把长数字转成科学计数法——这些得靠CSV头部加=或Excel预设列格式来防,MySQL层面根本管不了。










