Calcifer Calcifer 2
Sql

mysql查询结果直接导出excel

2019/05/15 19:38 5657 次阅读 王梓
打赏
✸ ✸ ✸

为什么需要导出 MySQL 数据到 Excel

日常运维和开发中,经常需要把数据库查询结果交给产品、运营或财务同事。他们最熟悉的工具就是 Excel。MySQL 本身提供了多种方式将查询结果导出为可被 Excel 打开的格式(CSV/TSV),下面从简单到进阶逐一介绍。

方法一:命令行重定向(最快)

最简单的方式,一行命令搞定:

mysql -uroot -p'yourpassword' dbname -e "SELECT * FROM temp LIMIT 100" > result.csv

原理:mysql 客户端默认以 Tab 分隔 输出结果(TSV 格式),用 > 重定向到文件。Excel 打开 TSV 文件时会自动识别 Tab 分隔符。

注意事项:

  • 密码建议用单引号包裹,避免特殊字符被 shell 解析
  • 输出的第一行是列名(字段名),Excel 会自动作为表头
  • 如果数据量很大,加 LIMIT 控制行数,避免内存溢出
  • 文件编码是 UTF-8,Excel 打开时需要选择 UTF-8 编码(否则中文乱码)

方法二:INTO OUTFILE(服务端导出)

如果你有服务器文件系统的写权限,可以用 MySQL 内置的 INTO OUTFILE 直接生成 CSV:

SELECT * FROM temp
INTO OUTFILE '/tmp/result.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

这种方式的特点:

  • 直接在 MySQL 服务端生成文件,速度最快
  • 输出的是标准 CSV 格式,逗号分隔,字段用双引号包裹
  • 文件生成在 MySQL 服务器本地,不是客户端机器
  • 不包含列名,只有数据行

常见报错及解决:

# 报错:The MySQL server is running with the --secure-file-priv option
# 查看允许的导出目录:
SHOW VARIABLES LIKE 'secure_file_priv';

# 解决:将导出路径改为该变量指定的目录
# 或者在 my.cnf 中设置 secure_file_priv = '' 然后重启 MySQL

如果想带上列名,可以用 UNION 的技巧:

SELECT 'id','name','email','created_at'
UNION ALL
SELECT id, name, email, created_at FROM users
INTO OUTFILE '/tmp/users.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

方法三:mysql 客户端 + sed 转 CSV

命令行重定向输出的是 TSV(Tab 分隔),如果需要标准 CSV(逗号分隔),可以用 sedtr 转换:

# Tab 转逗号
mysql -uroot -p'yourpassword' dbname -e "SELECT * FROM temp" | tr '\t' ',' > result.csv

# 或者用 sed,同时给字段加双引号
mysql -uroot -p'yourpassword' dbname -e "SELECT * FROM temp" | sed 's/\t/","/g; s/^/"/; s/$/"/' > result.csv

方法四:mysqldump 导出为 CSV

mysqldump 也支持导出为分隔符格式:

mysqldump -uroot -p'yourpassword' dbname temp \
  --tab=/tmp \
  --fields-terminated-by=',' \
  --fields-enclosed-by='"' \
  --lines-terminated-by='\n'

这会在 /tmp 下生成两个文件:temp.sql(表结构)和 temp.txt(数据)。数据文件可以直接用 Excel 打开。

方法五:Python 脚本导出为真正的 xlsx

如果需要生成真正的 Excel 文件(.xlsx),而不是 CSV,可以用 Python:

import pymysql
import openpyxl

conn = pymysql.connect(host='127.0.0.1', user='root',
                       password='yourpassword', database='dbname')
cur = conn.cursor()
cur.execute("SELECT * FROM temp")

wb = openpyxl.Workbook()
ws = wb.active
ws.title = "查询结果"

# 写入列名
ws.append([desc[0] for desc in cur.description])

# 写入数据
for row in cur.fetchall():
    ws.append(list(row))

wb.save("result.xlsx")
conn.close()
print("导出完成: result.xlsx")

安装依赖:pip install pymysql openpyxl

这种方式的优势:

  • 生成的是原生 xlsx 格式,不存在编码问题
  • 可以设置列宽、字体、颜色等样式
  • 可以处理多个 Sheet
  • 适合定时任务自动生成报表

Excel 打开 CSV 中文乱码的解决

这是最常见的坑。MySQL 导出的文件默认是 UTF-8 编码,但 Excel(尤其是 Windows 版)默认用 GBK/ANSI 打开,导致中文变成乱码。

解决方案:

方案 A:Excel 数据导入

  1. 打开 Excel,选择"数据" -> "从文本/CSV"
  2. 选择文件后,在预览界面将编码改为 65001: Unicode (UTF-8)
  3. 分隔符选择 Tab 或逗号(取决于你的导出方式)
  4. 点击"加载"

方案 B:添加 BOM 头

在文件开头加上 UTF-8 BOM 标记,Excel 就能自动识别编码:

# 导出时加 BOM
echo -e '\xEF\xBB\xBF' > result.csv
mysql -uroot -p'yourpassword' dbname -e "SELECT * FROM temp" | tr '\t' ',' >> result.csv

方案 C:转换为 GBK 编码

mysql -uroot -p'yourpassword' dbname -e "SELECT * FROM temp" | iconv -f utf-8 -t gbk > result.csv

实用技巧汇总

场景推荐方法说明
快速导出少量数据命令行重定向一行命令,最简单
大数据量导出INTO OUTFILE服务端直接写文件,最快
需要标准 CSV命令行 + tr/sed管道转换分隔符
需要 xlsx 格式Python + openpyxl原生 Excel,无编码问题
定时报表Python 脚本 + crontab自动化生成并发送邮件
Windows Excel 乱码加 BOM 或转 GBK解决中文编码问题

总结

MySQL 导出数据到 Excel 的核心思路就两条路:一是导出为 CSV/TSV 文本文件再用 Excel 打开,二是用脚本直接生成 xlsx。前者简单快速适合临时需求,后者灵活可控适合自动化场景。记住处理好 UTF-8 编码问题,基本就不会踩坑了。

✸ ✸ ✸

📜 版权声明

本文作者:王梓 | 原文链接:https://www.bthlt.com/note/307-Sqlmysql查询结果直接导出excel

出处:葫芦的运维日志 | 转载请注明出处并保留原文链接

📜 留言板

留言提交后需管理员审核通过才会显示