# ExcelXLL
**Repository Path**: mwmi/excel-xll-mingw
## Basic Information
- **Project Name**: ExcelXLL
- **Description**: 开发excel的xll扩展插件
- **Primary Language**: C++
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2024-05-13
- **Last Updated**: 2025-09-06
## Categories & Tags
**Categories**: Uncategorized
**Tags**: Excel
## README
# 📊 ExcelXLL
## 🤖 由 AI 生成 🤖
**✨ This Documentation is AI-Generated ✨**
---
> 🚀 支持 MinGW 和 MSVC 的现代 C++ Excel/WPS XLL 插件开发框架
[](https://isocpp.org/)
[](https://cmake.org/)
[](https://www.mingw-w64.org/)
[](https://visualstudio.microsoft.com/)
[](LICENSE)
## 📋 目录
- [📊 ExcelXLL](#-excelxll)
- [📋 目录](#-目录)
- [🎯 项目简介](#-项目简介)
- [✨ 最新更新 (v2.0)](#-最新更新-v20)
- [🏗️ 项目架构](#️-项目架构)
- [🚀 核心特性](#-核心特性)
- [📦 环境要求](#-环境要求)
- [🛠️ 快速开始](#️-快速开始)
- [📚 使用指南](#-使用指南)
- [📁 项目结构](#-项目结构)
- [🔧 构建配置](#-构建配置)
- [📝 API 文档](#-api-文档)
- [🧪 示例代码](#-示例代码)
- [❓ 常见问题](#-常见问题)
- [🤝 贡献指南](#-贡献指南)
- [📄 许可证](#-许可证)
## 🎯 项目简介
**ExcelXLL** 是一个功能强大的 Excel/WPS XLL 插件开发框架,使用现代 C++20 标准构建。该项目同时支持 **MinGW-w64** 和 **Microsoft Visual C++** 两种主流编译器,旨在简化 Excel 自定义函数的开发过程,为 C++ 开发者提供高效、易用的插件开发解决方案。
### 🎯 核心目标
- 🔧 **简化开发流程**:提供直观的 API 和宏定义,降低 XLL 开发门槛
- 🛡️ **内存安全**:采用 RAII 模式,自动管理资源,防止内存泄漏
- 📊 **数据处理**:强大的类型转换和数组操作能力
- 🔄 **跨平台兼容**:同时支持 32 位 WPS 和 64 位 Excel
- ⚡ **高性能**:优化的数据处理和内存管理机制
## ✨ 最新更新 (v3.0)
### 🔥 重大架构升级
#### 🚀 全新函数定义系统
- **📝 简化的UDF宏**:使用新的 `UDF()` 宏替代复杂的 `XLLUDFDEF` 和 `AUTOREGISTUDF`
- **⚡ 自动函数注册**:函数定义即自动注册,无需手动调用注册代码
- **🎯 灵活参数配置**:支持内联配置和映射表配置两种方式
- **📊 统一管理系统**:通过 `xllManager` 集中管理所有Excel函数
#### 🌐 RTD实时数据服务器
- **⏰ 实时数据推送**:完整的RTD (Real-Time Data) 协议实现
- **🔄 异步数据处理**:支持同步和异步两种RTD任务模式
- **📡 多数据源支持**:系统时钟、文件监控、网络数据等
- **🧵 多线程架构**:独立工作线程,不阻塞Excel主界面
- **📋 主题管理系统**:Topic类管理数据主题生命周期
#### 🛡️ 安全性与稳定性提升
- **🧠 RAII内存管理**:自动资源管理,防止内存泄漏
- **⚡ 优化性能表现**:减少内存分配,提升类型转换效率
- **🔍 错误处理机制**:完善的错误检测和恢复机制
#### 🔧 开发工具链优化
- **🏗️ 简化构建配置**:精简的CMakeLists.txt,自动检测架构
- **🌐 编译器兼容性**:完整支持MinGW和MSVC编译器
- **📝 UTF-8字符集**:统一使用UTF-8编码,解决中文显示问题
#### 📚 开发体验改进
- **📖 完整API文档**:所有公共接口提供详细的Doxygen注释
- **🧪 丰富示例代码**:UDF和RTD函数的完整使用示例
- **🛠️ 调试友好设计**:优化的错误信息和调试支持
### 📊 版本对比
| 特性 | v2.0 | v3.0 | 改进 |
|------|------|------|------|
| 函数定义复杂度 | 复杂 | 🟢 简化 | 🔺 70% |
| RTD实时数据 | 无 | 🟢 完整支持 | 🆕 新增 |
| 代码可维护性 | 一般 | 🟢 优秀 | 🔺 60% |
| 开发效率 | 中等 | 🟢 高效 | 🔺 50% |
| 功能丰富度 | 基础 | 🟢 全面 | 🔺 80% |
## 🏗️ 项目架构
项目采用分层架构设计,确保代码的可维护性和可扩展性:
```mermaid
graph TD
A[📋 函数定义层
functions.cpp] --> B[💼 管理层
xllManager]
B --> C[🔧 框架层
xllUDF + xllRTD]
C --> D[💎 核心类型层
xllType]
D --> E[🔌 接口层
XLCALL.H]
E --> F[📊 Excel/WPS XLL API]
G[⏰ RTD服务器
RtdServer] --> H[📡 数据主题
RTDTopic]
H --> I[🔄 COM接口
IRTDServer]
I --> F
style A fill:#e1f5fe
style B fill:#f3e5f5
style C fill:#e8f5e8
style D fill:#fff8e1
style E fill:#fff3e0
style F fill:#fce4ec
style G fill:#e8f5e8
style H fill:#f1f8e9
style I fill:#fce4ec
```
## 🚀 核心特性
### 💎 现代 C++ 特性
- 🔥 **C++20 标准支持**:使用最新的语言特性
- 🛡️ **RAII 内存管理**:自动资源管理,防止内存泄漏
- 📦 **模板编程**:类型安全的泛型编程支持
- 🔄 **STL 集成**:无缝集成标准模板库
### 📊 强大的数据处理
- 🔢 **多类型支持**:数字、字符串、布尔值、数组
- 🔄 **智能类型转换**:自动类型推断和转换
- 📋 **数组操作**:一维、二维数组的高效处理
- 🔍 **类型检测**:运行时类型安全检查
### 🔧 开发友好特性
- 🎯 **简化函数定义**:`UDF()` 宏一步到位定义和注册函数
- 🔄 **自动化管理**:`xllManager` 统一管理所有Excel函数
- 📝 **丰富文档**:完整的 API 文档和示例
- 🐛 **调试支持**:完善的 VSCode 调试配置
### 🔌 兼容性支持
- 📊 **Excel & WPS**:同时支持两大办公软件
- 🏗️ **32/64 位**:完整的架构支持
- 🔧 **多编译器**:MSVC 和 MinGW 双重支持
- 🌐 **Unicode**:完整的 Unicode 字符支持
## 📦 环境要求
### 🔧 必需工具
| 工具 | 版本要求 | 用途 |
|------|----------|------|
| **MSYS2** | 最新版 | 提供 MinGW 工具链 |
| **MinGW-w64** | GCC 11+ | C++ 编译器 |
| **MSVC** | VS 2019+ | 微软 C++ 编译器(可选)|
| **CMake** | 3.20+ | 构建系统 |
| **Ninja** | 最新版 | 构建工具 |
| **VSCode/Visual Studio** | 最新版 | 代码编辑器/IDE |
### 🔨 编译器支持
本项目支持两种主流编译器:
#### 🟢 **MinGW-w64** (推荐)
- ✅ **完整支持**:项目主要基于 MinGW 开发和测试
- 🌐 **跨平台**:兼容性更好,支持更多系统配置
- 📦 **便捷安装**:通过 MSYS2 一键安装完整工具链
- 🔧 **符号导出**:使用 `__attribute__((dllexport))`
#### 🔵 **Microsoft Visual C++ (MSVC)**
- ✅ **原生支持**:Windows 平台原生编译器
- 🚀 **性能优化**:更好的 Windows 平台优化
- 🛠️ **集成调试**:与 Visual Studio 完美集成
- 🔧 **符号导出**:使用 `__declspec(dllexport)`
- 📝 **UTF-8 支持**:自动配置字符集编码
### 🎯 目标平台
- **Windows 10/11** (x64)
- **Excel 2016+** (64位)
- **WPS Office** (32位)
## 🛠️ 快速开始
### 1️⃣ 环境配置
#### 🔨 方案一:使用 MinGW-w64 (推荐)
##### 📥 安装 MSYS2
```bash
# 下载并安装 MSYS2
# 官网:https://www.msys2.org/
# 更新系统
pacman -Syu
# 安装工具链
pacman -S mingw-w64-i686-toolchain \
mingw-w64-x86_64-toolchain \
mingw-w64-x86_64-cmake \
mingw-w64-x86_64-ninja
```
##### 🔧 配置环境变量
将以下路径添加到系统 PATH:
```
C:\msys64\mingw64\bin
C:\msys64\mingw32\bin
C:\msys64\usr\bin
```
#### 🔵 方案二:使用 Microsoft Visual C++ (MSVC)
##### 📥 安装 Visual Studio
1. **下载 Visual Studio 2019/2022**
- 官网:https://visualstudio.microsoft.com/downloads/
- 选择 Community/Professional/Enterprise 版本
2. **安装必需组件**
- ✅ C++ 核心功能
- ✅ MSVC v143 编译器工具集
- ✅ Windows 10/11 SDK
- ✅ CMake 工具
- ✅ Git for Windows
3. **选装组件** (推荐)
- ✨ IntelliCode
- ✨ Live Share
- ✨ 代码分析工具
##### 🛠️ 命令行工具安装
也可以单独安装命令行工具:
```bash
# 使用 Chocolatey 安装
choco install visualstudio2022buildtools --package-parameters "--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"
# 或使用 winget 安装
winget install Microsoft.VisualStudio.2022.BuildTools
# 安装 CMake
winget install Kitware.CMake
```
### 2️⃣ 编译项目
#### 🔨 使用 MinGW-w64 编译
```bash
# 克隆项目
git clone https://gitee.com/mwmi/excel-xll-mingw.git
cd excel-xll-mingw
# 32位构建 (WPS)
cmake -B build32 -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_SIZEOF_VOID_P=4
cmake --build build32
# 64位构建 (Excel)
cmake -B build64 -G Ninja -DCMAKE_CXX_STANDARD=20 -DCMAKE_SIZEOF_VOID_P=8
cmake --build build64
```
#### 🔵 使用 MSVC 编译
##### 🛠️ Visual Studio IDE 中编译
1. 打开 Visual Studio
2. 选择 "打开文件夹" → 选择项目根目录
3. Visual Studio 将自动检测 CMake 项目
4. 选择目标架构(x86 或 x64)
5. 点击 "生成" → "全部重新生成"
##### 📝 命令行编译
```cmd
# 使用 Visual Studio Developer Command Prompt
# 或在普通命令行中执行:
# “C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat”
# 克隆项目
git clone https://gitee.com/mwmi/excel-xll-mingw.git
cd excel-xll-mingw
# 32位构建 (WPS)
cmake -B build32 -G "Visual Studio 17 2022" -A Win32 -DCMAKE_CXX_STANDARD=20
cmake --build build32 --config Release
# 64位构建 (Excel)
cmake -B build64 -G "Visual Studio 17 2022" -A x64 -DCMAKE_CXX_STANDARD=20
cmake --build build64 --config Release
```
##### 🚀 使用 Ninja 生成器 (推荐)
```cmd
# 首先初始化 MSVC 环境
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
# 32位构建
cmake -B build32 -G Ninja -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_CXX_STANDARD=20 -DCMAKE_SIZEOF_VOID_P=4
cmake --build build32
# 64位构建
cmake -B build64 -G Ninja -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_CXX_STANDARD=20 -DCMAKE_SIZEOF_VOID_P=8
cmake --build build64
```
#### 🔍 编译器对比
| 特性 | MinGW-w64 | MSVC |
|------|-----------|------|
| **安装难度** | 🟢 简单 | 🟡 中等 |
| **编译速度** | 🟢 快 | 🟡 中等 |
| **调试支持** | 🟡 基础 | 🟢 强大 |
| **优化水平** | 🟡 好 | 🟢 优秀 |
| **兼容性** | 🟢 广泛 | 🟡 Windows |
| **编译输出** | `EXCELXLL_*.xll` | `EXCELXLL_*.xll` |
### 3️⃣ 加载插件
#### 📊 Excel 中加载
1. 打开 Excel
2. 进入 "开发工具" → "Excel 加载项"
3. 浏览选择 `build64/EXCELXLL_x64.xll`
#### 📝 WPS 中加载
1. 打开 WPS 表格
2. 进入 "开发工具" → "加载项"
3. 浏览选择 `build32/EXCELXLL_x86.xll`
## 📚 使用指南
### 🚀 快速创建UDF函数
使用新的 `UDF()` 宏可以快速定义Excel函数:
```cpp
#include "xllManager.h"
// 基础函数定义
UDF(Add, L"计算两个数的和", Param a, Param b) {
xllType result;
xllType a_ = a;
xllType b_ = b;
if (a_.is_num() && b_.is_num()) {
result = a_.get_num() + b_.get_num();
} else {
result = L"类型错误!";
}
return result.get_return();
}
// 带详细配置的函数定义
UDF(Concat2, ({
{udf::help, L"连接两个字符串"},
{udf::category, L"文本函数"}
}), Param a, Param b) {
xllType result;
xllType a_ = a;
xllType b_ = b;
std::wstring str = a_.get_str() + b_.get_str();
result = str;
return result.get_return();
}
// 在SET函数中进行全局配置
SET() {
xll::xllName = L"我的Excel插件";
xll::defaultCategory = L"自定义功能";
xll::open = []() {
// 插件加载时的初始化代码
return 1;
};
}
```
### ⏰ RTD实时数据函数
使用 `RTD()` 宏创建实时数据函数:
```cpp
// RTD时钟显示(异步)
RTD(RTDClock, L"显示实时时钟", ([](xllptrlist args, Topic* topic) {
SYSTEMTIME st;
while (true) {
GetLocalTime(&st);
wchar_t buffer[100];
swprintf(buffer, 100, L"🕒 %04d-%02d-%02d %02d:%02d:%02d",
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
topic->setValue(buffer);
Sleep(500);
}
return 0;
}, L"准备显示时钟...", true)) { // true表示异步执行
xllType ret;
CALLRTD(ret);
return ret.get_return();
}
// RTD参数传递(同步)
RTD(RTDParam, L"处理传入的参数", ([](xllptrlist args, Topic* topic) {
xllType result;
if (args.size() > 0) {
result = *args[0].get();
} else {
result = L"无参数";
}
topic->setValue(result);
return 0;
}, L"等待参数..."), Param input) {
xllType ret;
CALLRTD(ret, input);
return ret.get_return();
}
```
### 🔄 数据类型转换
`xllType` 类支持多种数据类型的智能转换:
```cpp
// 数值操作
xllType num = 3.14;
double value = num.get_num();
// 字符串操作
xllType str = L"Hello, Excel!";
std::wstring text = str.get_str();
// 数组操作
xllType array = some_range;
for (auto& cell : array) {
if (cell->is_num()) {
double val = cell->get_num();
// 处理数值
}
}
// 二维数组访问
xllType matrix = some_matrix;
for (int row = 0; row < matrix.rows; ++row) {
for (int col = 0; col < matrix.cols; ++col) {
xllType* cell = matrix.at(row, col);
// 处理单元格数据
}
}
```
### 🛡️ 错误处理
框架提供了完善的错误处理机制:
```cpp
UDF(SafeDivide, L"安全除法运算", Param a, Param b) {
xllType result;
xllType dividend = a;
xllType divisor = b;
// 类型检查
if (!dividend.is_num() || !divisor.is_num()) {
result.set_err(xlerrValue); // #VALUE! 错误
return result.get_return();
}
double div_val = divisor.get_num();
if (div_val == 0.0) {
result.set_err(xlerrDiv0); // #DIV/0! 错误
return result.get_return();
}
result = dividend.get_num() / div_val;
return result.get_return();
}
```
## 📁 项目结构
```
ExcelXLL/
├── 📁 include/ # 头文件目录
│ ├── 🔧 XLCALL.H # Excel XLL API 接口
│ ├── 💎 xllType.h # 核心数据类型封装
│ ├── 🎯 xllManager.h # XLL管理器(统一入口)
│ ├── 🔧 xllMacros.h # UDF和RTD宏定义
│ ├── 📋 xllUDF.h # 用户定义函数框架
│ ├── ⏰ xllRTD.h # RTD实时数据框架
│ ├── 🛠️ xllTools.h # 工具函数
│ ├── 📡 RtdServer.h # RTD服务器核心类
│ ├── 📊 RTDTopic.h # RTD主题管理
│ ├── 🔌 IRTDServer.h # RTD COM接口
│ └── 🏗️ dll.h # DLL导出定义
├── 📁 src/ # 源文件目录
│ ├── 🔧 XLCALL.CPP # Excel API 实现
│ ├── 💎 xllType.cpp # 数据类型实现
│ ├── 🎯 xllManager.cpp # 管理器实现
│ ├── 📋 xllUDF.cpp # UDF 框架实现
│ ├── ⏰ xllRTD.cpp # RTD 框架实现
│ ├── 🛠️ xllTools.cpp # 工具函数实现
│ ├── 📡 RtdServer.cpp # RTD服务器实现
│ ├── 📊 RTDTopic.cpp # RTD主题实现
│ └── 🏗️ dll.cpp # DLL入口点实现
├── 📁 lib/ # 静态库文件
│ ├── 📚 XLCALL32.LIB # 32位 Excel 库
│ └── 📁 x64/
│ └── 📚 XLCALL32.LIB # 64位 Excel 库
├── 🔧 CMakeLists.txt # CMake 构建配置
├── 🚀 functions.cpp # 示例函数实现(主要开发文件)
├── 📄 dll.def # DLL导出定义文件
├── 📄 LICENSE # MIT许可证
└── 📖 README.md # 项目文档
```
## 🔧 构建配置
### 📋 CMake 配置选项
| 选项 | 默认值 | 说明 |
|------|--------|------|
| `CMAKE_CXX_STANDARD` | 20 | C++ 标准版本 |
| `CMAKE_SIZEOF_VOID_P` | 自动检测 | 指针大小(4=32位,8=64位)|
| `CMAKE_BUILD_TYPE` | Release | 构建类型 |
| `CMAKE_C_COMPILER` | 自动检测 | C 编译器路径 |
| `CMAKE_CXX_COMPILER` | 自动检测 | C++ 编译器路径 |
### 🔨 编译器特定配置
#### 🟢 MinGW-w64 配置
```bash
# 基础配置
cmake -B build -G Ninja \
-DCMAKE_CXX_STANDARD=20 \
-DCMAKE_SIZEOF_VOID_P=8
# 指定 GCC 版本
cmake -B build -G Ninja \
-DCMAKE_C_COMPILER=gcc \
-DCMAKE_CXX_COMPILER=g++ \
-DCMAKE_CXX_STANDARD=20
# 使用特定 MinGW 路径
cmake -B build -G Ninja \
-DCMAKE_C_COMPILER="C:/msys64/mingw64/bin/gcc.exe" \
-DCMAKE_CXX_COMPILER="C:/msys64/mingw64/bin/g++.exe" \
-DCMAKE_CXX_STANDARD=20
```
#### 🔵 MSVC 配置
```cmd
# 使用 Visual Studio 生成器
cmake -B build -G "Visual Studio 17 2022" \
-A x64 \
-DCMAKE_CXX_STANDARD=20
# 使用 Ninja 生成器 + MSVC
cmake -B build -G Ninja \
-DCMAKE_C_COMPILER=cl \
-DCMAKE_CXX_COMPILER=cl \
-DCMAKE_CXX_STANDARD=20
# 指定 MSVC 工具集版本
cmake -B build -G Ninja \
-DCMAKE_C_COMPILER=cl \
-DCMAKE_CXX_COMPILER=cl \
-DCMAKE_CXX_STANDARD=20 \
-T v143
# 启用特定编译选项
cmake -B build -G Ninja \
-DCMAKE_C_COMPILER=cl \
-DCMAKE_CXX_COMPILER=cl \
-DCMAKE_CXX_STANDARD=20 \
-DCMAKE_CXX_FLAGS="/W4 /WX" \
-DCMAKE_C_FLAGS="/W4 /WX"
```
### 🎯 目标架构配置
```bash
# MinGW: 强制32位构建
cmake -B build32 -G Ninja -DCMAKE_SIZEOF_VOID_P=4
# MinGW: 强制64位构建
cmake -B build64 -G Ninja -DCMAKE_SIZEOF_VOID_P=8
# MSVC: 32位构建
cmake -B build32 -G "Visual Studio 17 2022" -A Win32
# MSVC: 64位构建
cmake -B build64 -G "Visual Studio 17 2022" -A x64
# 调试版本构建
cmake -B debug -G Ninja -DCMAKE_BUILD_TYPE=Debug
```
### 🚀 性能优化配置
#### 发布版本优化
```bash
# MinGW 高度优化
cmake -B release -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="-O3 -march=native -flto" \
-DCMAKE_C_FLAGS="-O3 -march=native -flto"
# MSVC 高度优化
cmake -B release -G Ninja \
-DCMAKE_C_COMPILER=cl \
-DCMAKE_CXX_COMPILER=cl \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="/O2 /GL /LTCG" \
-DCMAKE_C_FLAGS="/O2 /GL /LTCG"
```
#### 调试版本配置
```bash
# MinGW 调试配置
cmake -B debug -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="-g3 -O0 -fsanitize=address" \
-DCMAKE_C_FLAGS="-g3 -O0 -fsanitize=address"
# MSVC 调试配置
cmake -B debug -G "Visual Studio 17 2022" \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="/Zi /Od /RTC1" \
-DCMAKE_C_FLAGS="/Zi /Od /RTC1"
```
### 🔄 构建输出
| 架构 | 输出文件 | 目标软件 | 编译器支持 |
|------|----------|----------|------------|
| 32位 | `EXCELXLL_x86.xll` | WPS Office | MinGW + MSVC |
| 64位 | `EXCELXLL_x64.xll` | Microsoft Excel | MinGW + MSVC |
### 🛠️ 编译器对比详细
| 特性 | MinGW-w64 | MSVC | 说明 |
|------|-----------|------|------|
| **安装复杂度** | 🟢 简单 | 🟡 中等 | MSYS2 vs Visual Studio |
| **编译速度** | 🟢 快 | 🟡 中等 | GCC 编译速度更快 |
| **调试体验** | 🟡 GDB | 🟢 强大 | Visual Studio 调试器更好 |
| **代码优化** | 🟡 好 | 🟢 优秀 | MSVC 优化更好 |
| **C++20 支持** | 🟢 完整 | 🟢 完整 | 都支持最新标准 |
| **静态链接** | 🟢 简单 | 🟡 复杂 | MinGW 更容易部署 |
| **跨平台** | 🟢 广泛 | 🟡 Windows | GCC 兼容性更好 |
| **体积大小** | 🟢 小 | 🟡 大 | 生成文件更小 |
## 📝 API 文档
### 💎 xllType 类核心方法
#### 🔍 类型检测方法
```cpp
bool is_num() // 是否为数值
bool is_str() // 是否为字符串
bool is_bool() // 是否为布尔值
bool is_array() // 是否为数组
bool is_sref() // 是否为单元格引用
bool is_empty() // 是否为空值
bool is_error() // 是否为错误值
```
#### 📊 数据获取方法
```cpp
double get_num() // 获取数值
std::wstring get_str() // 获取字符串
bool get_bool() // 获取布尔值
int get_last_err() // 获取最后错误码
LPXLOPER12 get_return() // 获取返回值指针
```
#### 🔄 数组操作方法
```cpp
int size() const // 获取数组大小
xllType* at(int i) // 一维索引访问
xllType* at(int row, int col) // 二维索引访问
xllType* operator[](int i) // 下标操作符
xllType* push_back(xllType&) // 添加元素
// 迭代器支持
Iter begin() // 开始迭代器
Iter end() // 结束迭代器
```
#### ⚡ 赋值操作符
```cpp
xllType& operator=(double) // 数值赋值
xllType& operator=(const wchar_t*) // 字符串赋值
xllType& operator=(const std::wstring&) // 宽字符串赋值
xllType& operator=(const XllList&) // 列表赋值
xllType& operator=(const XllMatrix&) // 矩阵赋值
```
### 🎯 新函数定义系统
#### `UDF` - 用户自定义函数
```cpp
// 基础语法
UDF(函数名, L"函数描述", [参数列表]) {
// 函数实现
}
// 带配置的语法
UDF(函数名, ({
{udf::help, L"详细帮助信息"},
{udf::category, L"函数分类"},
{udf::shortcut, L"快捷键"}
}), [参数列表]) {
// 函数实现
}
```
#### `RTD` - 实时数据函数
```cpp
RTD(函数名, L"函数描述", (任务函数, 默认值, 是否异步), [参数列表]) {
xllType ret;
CALLRTD(ret, [参数列表]);
return ret.get_return();
}
```
#### `SET` - 全局配置
```cpp
SET() {
xll::xllName = L"插件名称";
xll::defaultCategory = L"默认分类";
xll::enableRTD = true; // 启用RTD服务
xll::open = []() {
// 插件加载时执行
return 1;
};
}
```
#### 📋 配置选项说明
| 选项 | 类型 | 说明 |
|------|------|------|
| `udf::help` | wstring | 函数帮助信息 |
| `udf::category` | wstring | 函数分类 |
| `udf::shortcut` | wstring | 快捷键 |
| `Param` | 参数标识 | 定义函数参数 |
## 🧪 示例代码
### 📊 数学计算函数
```cpp
/**
* @brief 计算数组平均值
*/
UDF(Average, L"计算数组平均值", Param range) {
xllType result;
xllType data = range;
if (!data.is_array()) {
result.set_err(xlerrValue);
return result.get_return();
}
double sum = 0.0;
int count = 0;
for (auto& cell : data) {
if (cell->is_num()) {
sum += cell->get_num();
count++;
}
}
if (count == 0) {
result.set_err(xlerrDiv0);
} else {
result = sum / count;
}
return result.get_return();
}
/**
* @brief 数组求和(更简洁的写法)
*/
UDF(MySum, L"数组求和", Param a) {
xllType result;
xllType a_ = a;
double sum = 0;
if (a_.is_array()) {
for (auto i : a_) {
if (i->is_num())
sum += i->get_num();
}
}
result = sum;
return result.get_return();
}
```
### 🔤 字符串处理函数
```cpp
/**
* @brief 字符串连接函数
*/
UDF(ConcatRange, ({
{udf::help, L"连接数组中的所有文本,支持自定义分隔符"},
{udf::category, L"文本函数"}
}), Param range, Param separator) {
xllType result;
xllType data = range;
xllType sep = separator;
std::wstring sep_str = sep.is_str() ? sep.get_str() : L",";
std::wstring output;
bool first = true;
if (data.is_array()) {
for (auto& cell : data) {
if (cell->is_str() || cell->is_num()) {
if (!first) output += sep_str;
output += cell->get_str();
first = false;
}
}
} else {
output = data.get_str();
}
result = output;
return result.get_return();
}
/**
* @brief 简单字符串拼接
*/
UDF(Concat2, L"拼接两个字符串", Param a, Param b) {
xllType result;
xllType a_ = a;
xllType b_ = b;
std::wstring str = a_.get_str() + b_.get_str();
result = str;
return result.get_return();
}
```
### 🔍 查找与RTD函数
```cpp
/**
* @brief 在数组中查找指定值
*/
UDF(FindInArray, L"在数组中查找指定值", Param search_array, Param search_value) {
xllType result;
xllType array = search_array;
xllType target = search_value;
if (!array.is_array()) {
result.set_err(xlerrValue);
return result.get_return();
}
for (int i = 0; i < array.size(); ++i) {
xllType* cell = array[i];
if ((cell->is_num() && target.is_num() &&
cell->get_num() == target.get_num()) ||
(cell->is_str() && target.is_str() &&
cell->get_str() == target.get_str())) {
result = static_cast(i + 1); // Excel 索引从1开始
return result.get_return();
}
}
result.set_err(xlerrNA); // #N/A 未找到
return result.get_return();
}
/**
* @brief RTD返回数组示例
*/
RTD(RTDArray, L"返回实时数组数据", ([](xllptrlist args, Topic* topic) {
xllType a = 10.123;
xllType b = L"文本";
xllType c = 20;
xllType d = L"更多文本";
xllType ret({{a,b},{c,d}}); // 创建2x2数组
topic->setValue(ret);
return 0;
}, L"准备数据中...")) {
xllType ret;
CALLRTD(ret);
return ret.get_return();
}
```
## ❓ 常见问题
### 🐛 编译问题
**Q: 编译时出现 "无法找到 XLCALL32.LIB"**
```bash
A: 确保 lib 目录结构正确:
lib/XLCALL32.LIB # 32位库
lib/x64/XLCALL32.LIB # 64位库
```
**Q: 如何使用新的UDF宏系统?**
```cpp
A: 使用UDF宏替代旧语法:
UDF(MyFunction, L"函数描述", Param a, Param b) {
// 函数实现
return result.get_return();
}
```
**Q: 如何创建RTD实时数据函数?**
```cpp
A: 使用RTD宏创建实时数据函数:
RTD(MyRTD, L"实时数据", ([](xllptrlist args, Topic* topic) {
topic->setValue(L"实时值");
return 0;
}, L"默认值")) {
xllType ret;
CALLRTD(ret);
return ret.get_return();
}
```
A: 确保 lib 目录结构正确:
lib/XLCALL32.LIB # 32位库
lib/x64/XLCALL32.LIB # 64位库
```
**Q: 编译时出现字符编码错误**
```bash
A: 在 CMakeLists.txt 中已添加 UTF-8 支持,
确保使用最新版本的项目配置
```
### 🔧 运行时问题
**Q: Excel 无法加载 XLL 文件**
```bash
A: 检查以下几点:
1. 确保使用正确的架构版本(32位用于WPS,64位用于Excel)
2. 检查 Excel 的宏安全设置
3. 确保所有依赖的 DLL 文件存在
```
**Q: 函数调用时返回 #VALUE! 错误**
```bash
A: 常见原因:
1. 参数类型不匹配
2. 函数内部逻辑错误
3. 内存管理问题
建议使用 get_last_err() 获取详细错误码
```
### 💡 性能优化
**Q: 如何优化大数组处理性能?**
```cpp
A: 使用以下技巧:
1. 减少内存分配:复用 xllType 对象
2. 批量处理:避免逐个单元格操作
3. 类型检查:提前进行类型验证
4. 迭代器:使用 for-each 而非索引访问
```
### 🔄 内存管理
**Q: 如何避免内存泄漏?**
```cpp
A: 遵循以下原则:
1. 使用 RAII:让框架自动管理内存
2. 避免手动 new/delete:使用智能指针
3. 及时返回:使用 get_return() 转移所有权
4. 检查工具:定期使用内存检测工具
```
## 🤝 贡献指南
### 📋 开发流程
1. **🍴 Fork 项目**
```bash
git clone https://gitee.com/mwmi/excel-xll-mingw.git
```
2. **🌿 创建特性分支**
```bash
git checkout -b feature/your-feature-name
```
3. **✍️ 提交更改**
```bash
git commit -m "✨ 添加新功能: 您的功能描述"
```
4. **🚀 推送分支**
```bash
git push origin feature/your-feature-name
```
5. **📝 提交 Pull Request**
### 📏 代码规范
- **🎯 命名约定**: 使用 camelCase 命名函数,PascalCase 命名类
- **📝 注释规范**: 使用 Doxygen 风格注释
- **🔧 代码风格**: 遵循现有代码风格
- **✅ 测试覆盖**: 新功能需要添加相应测试
### 🐛 问题报告
提交问题时请包含:
- 📋 问题描述和重现步骤
- 💻 系统环境信息
- 📄 相关代码片段
- 🔍 错误日志信息
### 💡 功能请求
- 📝 详细描述期望功能
- 🎯 说明使用场景
- 💭 提供设计思路(可选)
## 📄 许可证
本项目采用 [MIT 许可证](LICENSE) 开源。
```
MIT License
Copyright (c) 2024 mwmi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
```
---
### 🌟 如果这个项目对您有帮助,请给我们一个 Star!
**开发者**: [mwmi](https://gitee.com/mwmi) | **项目地址**: [excel-xll](https://gitee.com/mwmi/excel-xll-mingw)
**技术交流** 🤝 | **问题反馈** 🐛 | **功能建议** 💡