问题描述
你花了整整一个小时在 DuckDB 里清洗数据。查询完美,结果就绪。现在需要把报告发给领导——但领导只看 Excel 文件。
传统流程:
- 从 DuckDB 导出 CSV
- 打开 Python/Pandas
- CSV 转 Excel
- 保存 .xlsx
- 发送文件
5 个步骤,本来1 步就能搞定。
一招解决
COPY (
SELECT
product_name,
SUM(sales) AS total_sales,
AVG(price) AS avg_price,
COUNT(*) AS orders
FROM orders
WHERE order_date >= '2026-01-01'
GROUP BY product_name
ORDER BY total_sales DESC
) TO 'sales_report.xlsx' (HEADER, MODE_CSV);
就这一句。 一条 SQL。不用 Python。不用 Pandas。不用中间格式。
原理解析
DuckDB 的 COPY TO 命令支持多种输出格式:
-- 导出 Excel (.xlsx)
COPY (SELECT * FROM my_table) TO 'output.xlsx' (HEADER);
-- 导出 CSV
COPY (SELECT * FROM my_table) TO 'output.csv' (HEADER);
-- 导出 Parquet
COPY (SELECT * FROM my_table) TO 'output.parquet';
-- 导出 JSON
COPY (SELECT * FROM my_table) TO 'output.json';
效果量化
| 方法 | 代码行数 | 耗时 | 内存占用 |
|---|---|---|---|
| DuckDB COPY TO | 1 行 | ~2 秒 | 极小 |
| Python + Pandas | 5-10 行 | ~8 秒 | 高(需加载完整 dataframe) |
| CSV 导出 + 手动转换 | 3+ 步骤 | ~15 秒 | 中等 |
100MB 查询结果实测:
- DuckDB COPY:直接流式输出,内存峰值约 200MB
- Pandas to_excel:先全部加载到内存,峰值 1GB+
使用场景
- 向管理层发送周报(Excel 格式)
- 导出分析结果给非技术同事
- 为不用 DuckDB 的同事创建数据包
- 快速 ad-hoc 导出,无需写 Python 脚本
注意事项
唯一限制:Excel 导出不支持复杂数据类型(数组、结构体)。遇到这些类型,改用 Parquet 或 JSON 导出。
一句话总结
导出数据优先用 COPY TO。 更快、更省内存、零额外工具依赖。
订阅 DuckDB Lab,每周三获取一个马上能用的实战技巧。🦆