# xl_duckdb **Repository Path**: LeeExcel/xl_duckdb ## Basic Information - **Project Name**: xl_duckdb - **Description**: No description available - **Primary Language**: C++ - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-25 - **Last Updated**: 2026-04-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # xl_DuckDb - DuckDB SQL Query Engine for Excel 在 Excel 中直接执行 DuckDB SQL 查询,支持 CSV、JSON、Parquet 等数据源,返回动态数组结果。 ## 致谢 本项目受到 [RusselWebber/xlDuckDb] 的启发,感谢原作者的优秀工作! 本实现使用 C++ 重新编写,具有以下改进: - 更小的二进制体积(~600KB vs ~2MB) - 无需 MSVC 运行时依赖 - 优化的大数据集处理性能 - 清晰的目录结构和自动化构建 ## 快速开始 ### 1. 编译 ```bash cd c:\xll_cpp .\build.bat ``` 编译产物位于 `bin/` 目录: - `xl_duckdb.xll` - Excel 插件 - `duckdb.dll` - DuckDB 运行时库(自动复制) ### 2. 加载 XLL 1. 打开 Excel 或 WPS 表格 2. 文件 → 选项 → 加载项 → 浏览 3. 选择 `bin/xl_duckdb.xll` 4. 确认加载 ### 3. 使用函数 ```excel =DuckDbQuery(sql, [db_path], [range1], [range2], [range3], [range4], [range5]) ``` **参数说明:** - `sql` (必需) - SQL 查询语句 - `db_path` (可选) - DuckDB 数据库文件路径,默认为内存数据库 - `range1-5` (可选) - Excel 区域引用,在 SQL 中通过 `xlRange1` ~ `xlRange5` 访问 --- ## SQL 公式演示 ### 基础查询 ```excel ' 简单计算 =DuckDbQuery("SELECT 1+2 AS result") ' 字符串操作 =DuckDbQuery("SELECT upper('hello') AS greeting") ' 日期函数 =DuckDbQuery("SELECT current_date AS today") ``` ### 查询 Excel 区域数据 假设 A1:B10 包含数据(第1行为标题): ```excel ' 查询整个区域 =DuckDbQuery("SELECT * FROM xlRange1", , A1:B10) ' 聚合查询 =DuckDbQuery("SELECT category, SUM(amount) AS total FROM xlRange1 GROUP BY category", , A1:B10) ' 条件过滤 =DuckDbQuery("SELECT * FROM xlRange1 WHERE amount > 100", , A1:B10) ' 排序 =DuckDbQuery("SELECT * FROM xlRange1 ORDER BY amount DESC", , A1:B10) ``` ### 多区域联合查询 ```excel ' JOIN 两个区域 =DuckDbQuery( "SELECT a.name, b.amount FROM xlRange1 a JOIN xlRange2 b ON a.id = b.id", , A1:B10, ' xlRange1 D1:E10 ' xlRange2 ) ' UNION 合并 =DuckDbQuery( "SELECT * FROM xlRange1 UNION ALL SELECT * FROM xlRange2", , A1:C5, E1:G5 ) ``` ### 查询 CSV 文件 ```excel ' 读取 CSV(自动推断类型) =DuckDbQuery("SELECT * FROM 'C:/data/sales.csv'") ' 或者使用 read_csv 函数 =DuckDbQuery("SELECT * FROM read_csv('C:/data/sales.csv')") ' 指定分隔符 =DuckDbQuery("SELECT * FROM read_csv('C:/data/data.tsv', delim='\t')") ' 查询后聚合 =DuckDbQuery(" SELECT product, SUM(quantity) AS total_qty FROM 'C:/data/sales.csv' GROUP BY product ORDER BY total_qty DESC ") ``` ### 查询 Parquet 文件 ```excel ' 读取 Parquet =DuckDbQuery("SELECT * FROM 'C:/data/large_dataset.parquet'") ' 列裁剪(只读取需要的列,提升性能) =DuckDbQuery(" SELECT customer_id, order_date, amount FROM 'C:/data/orders.parquet' WHERE order_date >= '2024-01-01' ") ``` ### 查询 JSON 文件 ```excel ' 读取 JSON(直接查询文件) =DuckDbQuery("SELECT * FROM 'C:/data/data.json'") ' 或者使用 read_json 函数 =DuckDbQuery("SELECT * FROM read_json('C:/data/data.json')") ' JSON 嵌套字段 =DuckDbQuery(" SELECT user->>'name' AS name, user->>'age' AS age FROM 'C:/data/users.json' ") ``` ### 远程数据源 ```excel ' HTTPS URL =DuckDbQuery("SELECT * FROM 'https://example.com/data.parquet'") ' S3(需要配置凭证) =DuckDbQuery(" SELECT * FROM 's3://my-bucket/data.parquet' ") ``` ### 高级 SQL 功能 ```excel ' 窗口函数 =DuckDbQuery(" SELECT name, amount, RANK() OVER (ORDER BY amount DESC) AS rank FROM xlRange1 ", , A1:B10) ' CTE(公用表表达式) =DuckDbQuery(" WITH sales_summary AS ( SELECT product, SUM(amount) AS total FROM xlRange1 GROUP BY product ) SELECT * FROM sales_summary WHERE total > 1000 ", , A1:C100) ' 子查询 =DuckDbQuery(" SELECT * FROM xlRange1 WHERE amount > (SELECT AVG(amount) FROM xlRange1) ", , A1:B10) ' CASE 表达式 =DuckDbQuery(" SELECT name, CASE WHEN amount >= 1000 THEN 'High' WHEN amount >= 500 THEN 'Medium' ELSE 'Low' END AS level FROM xlRange1 ", , A1:B10) ``` ### 持久化数据库 ```excel ' 创建持久化数据库 =DuckDbQuery("CREATE TABLE users (id INTEGER, name VARCHAR)", "C:/data/mydb.duckdb") ' 插入数据 =DuckDbQuery("INSERT INTO users VALUES (1, 'Alice'), (2, 'Bob')", "C:/data/mydb.duckdb") ' 查询持久化数据库 =DuckDbQuery("SELECT * FROM users", "C:/data/mydb.duckdb") ``` --- ## 支持的 DuckDB 特性 ✅ **数据格式** - CSV (直接查询 `.csv` 文件或 `read_csv()`) - JSON (直接查询 `.json` 文件或 `read_json()`) - Parquet (直接查询 `.parquet` 文件) - Excel 区域(通过 `xlRange1` ~ `xlRange5`) ✅ **SQL 标准** - SELECT, INSERT, UPDATE, DELETE - JOIN (INNER, LEFT, RIGHT, FULL) - GROUP BY, HAVING - ORDER BY, LIMIT - 子查询、CTE - 窗口函数 - 聚合函数(SUM, AVG, COUNT, MIN, MAX 等) ✅ **数据类型** - 整数(TINYINT, SMALLINT, INTEGER, BIGINT, HUGEINT) - 浮点数(FLOAT, DOUBLE) - 布尔值(BOOLEAN) - 字符串(VARCHAR) - 日期时间(DATE, TIME, TIMESTAMP) ✅ **高级功能** - 远程数据源(HTTPS, S3) - 压缩文件(自动解压 .gz, .zst) - 分区 Parquet 查询 - 全文搜索 --- ## 性能优化建议 ### 1. 大数据集处理 对于超过 10 万行的数据: ```excel ' 使用列裁剪减少 I/O =DuckDbQuery("SELECT col1, col2 FROM 'large.parquet'", , ...) ' 提前过滤减少数据量 =DuckDbQuery("SELECT * FROM xlRange1 WHERE date >= '2024-01-01'", , A1:Z100000) ``` ### 2. 使用 Parquet 代替 CSV Parquet 格式比 CSV 快 10-100 倍: ```excel ' 慢:CSV =DuckDbQuery("SELECT * FROM 'data.csv'") ' 快:Parquet =DuckDbQuery("SELECT * FROM 'data.parquet'") ``` ### 3. 避免不必要的列 ```excel ' 不好:读取所有列 =DuckDbQuery("SELECT * FROM xlRange1", , A1:Z1000) ' 好:只读取需要的列 =DuckDbQuery("SELECT name, amount FROM xlRange1", , A1:Z1000) ``` --- ## 故障排查 ### 问题:加载 XLL 后函数不可用 **解决:** 1. 确认 `duckdb.dll` 与 `xl_duckdb.xll` 在同一目录 2. 检查 Excel 信任中心设置,允许加载项 3. 查看日志文件:`%TEMP%\xll_debug.log` ### 问题:查询返回 #VALUE! 错误 **原因:** SQL 语法错误或区域引用无效 **解决:** 1. 在 DuckDB CLI 中测试 SQL 2. 检查区域引用是否正确 3. 查看日志文件获取详细错误信息 ### 问题:大数据集卡死 **解决:** 1. 使用列裁剪减少数据量 2. 提前过滤(WHERE 子句) 3. 使用 Parquet 格式代替 CSV 4. 避免在单元格中使用过多公式 --- ## 项目结构 ``` c:\xll_cpp/ ├── bin/ # 编译输出 │ ├── xl_duckdb.xll # Excel 插件 │ └── duckdb.dll # DuckDB 运行时 ├── lib/ │ ├── excel/ # Excel SDK │ │ ├── xlcall.h │ │ └── XLCALL32.LIB │ └── libduckdb/ # DuckDB SDK │ ├── duckdb.h │ ├── duckdb.dll │ └── ... ├── xl_duckdb.cpp # 源代码 ├── xl_duckdb.def # 模块定义 ├── build.bat # 编译脚本 └── README.md # 本文档 ``` --- ## 编译说明 ### MinGW (g++) ```bash cd c:\xll_cpp .\build.bat ``` --- ## 更新日志 ### v0.12 (2026-04-25) - ✅ 修复 DuckDB 结构体定义问题 - ✅ 优化大结果集性能(移除单元格级别日志) - ✅ 支持 HUGEINT 类型 - ✅ 重构目录结构(bin/, lib/excel/, lib/libduckdb/) - ✅ 自动复制 duckdb.dll 到 bin 目录 ### v0.11 - 初始版本 --- ## 许可证 MIT License --- ## 致谢与参考 - **[RusselWebber/xlDuckDb](https://github.com/RusselWebber/xlDuckDb)** - 原始 xlDuckDb 项目,本项目的灵感来源 - **[DuckDB](https://duckdb.org/)** - 强大的嵌入式分析数据库 - **[Excel XLL SDK](https://learn.microsoft.com/en-us/office/client-developer/excel/welcome-to-the-excel-software-development-kit)** - Microsoft Excel C API 文档 --- ## 相关链接 - [DuckDB 官方文档](https://duckdb.org/docs/) - [DuckDB SQL 参考](https://duckdb.org/docs/sql/introduction.html) - [Excel XLL SDK](https://learn.microsoft.com/en-us/office/client-developer/excel/welcome-to-the-excel-software-development-kit)