应选 xlnt 读 .xlsx、libxls 读 .xls;libxlsxwriter 仅支持写入,不可用于读取。xlnt 基于 C++14,头文件库,需关 zlib 以避免跨平台编译问题;libxls 为 C 风格,须手动初始化和内存管理。

用 libxlsxwriter 还是 libxls?别选错方向
读 Excel 不是写 Excel,libxlsxwriter 只能写不能读,硬塞进去会编译失败或运行时崩溃。真正能读 .xlsx 的主流 C++ 库是 libxlsxreader 或更常用的 xlnt;读老式 .xls 则得靠 libxls。选错库第一行代码就报错:undefined reference to 'xlsx::document::load' 或直接链接失败。
-
xlnt支持 .xlsx(OpenXML),C++14 起,头文件为主,无外部依赖 -
libxls仅支持 .xls(BIFF 格式),C 风格 API,需手动管理内存 - 别碰
libxlsxwriter——它没提供任何读取接口
xlnt 读取 Excel 到二维 std::vector<:vector>></:vector> 的最小可行路径
不是所有单元格都要转成字符串,但统一用 std::string 最省事,避免类型判断逻辑爆炸。关键在跳过空行、处理合并单元格(xlnt 默认展开,值只在左上角)、以及识别真实数据范围(别把表头当空行跳过)。
- 用
xlnt::workbook wb; wb.load("data.xlsx");加载,失败会抛xlnt::exception - 取首工作表:
auto ws = wb.active_sheet();,别用sheet_by_index(0)——索引可能越界 - 用
ws.dimensions()拿到有效区域,比遍历全表快得多;否则空行多时性能骤降 - 逐行遍历时,对每个
cell调用cell.to_string(),它自动处理数字/日期/布尔的格式化转换
std::vector<std::vector<std::string>> data;
auto dim = ws.dimensions();
for (size_t r = dim.first.row(); r <= dim.last.row(); ++r) {
std::vector<std::string> row;
for (size_t c = dim.first.column(); c <= dim.last.column(); ++c) {
auto cell = ws.cell(xlnt::cell_reference(c, r));
row.push_back(cell.to_string());
}
data.push_back(row);
}
为什么 libxls 读 .xls 容易崩在 xls_getCell 上?
因为 libxls 是纯 C 库,不自动初始化结构体字段,XLSTABLE 和 XLSWORKBOOK 必须先 memset 清零,否则 xls_getCell 读到野指针就段错误。而且它不区分“空单元格”和“未定义单元格”,同一行里中间空一列,下标直接断掉,必须用 row->cells.count 动态查长度。
- 加载前必须:
memset(&wb, 0, sizeof(xlsWorkBook)); - 每行要先
row = xls_row(&wb, sheet, r),再循环row->cells.count,不能硬写for (int c = 0; c - 单元格内容用
row->cells.cell[c].str访问,但str可能为nullptr,得判空再strcpy - 读完必须调
xls_close(&wb),否则内存泄漏,且下次xls_open可能失败
跨平台编译时 xlnt 找不到 zlib 怎么办?
xlnt 默认启用 zlib 解压,但 Windows 下不自带,Linux/macOS 通常有。CMake 找不到 ZLIB_LIBRARY 就卡在 configure 阶段,错误信息是:CMake Error: Could not find zlib。关掉压缩支持最稳,虽然文件大一点,但免去环境适配麻烦。
立即学习“C++免费学习笔记(深入)”;
- CMake 命令加参数:
-DXLNT_USE_ZLIB=OFF - 或者改
CMakeLists.txt:在find_package(ZLIB QUIET)后加set(XLNT_USE_ZLIB OFF) - 关 zlib 后,
.xlsx仍可读,只是无法处理某些压缩异常的文件(极少见) - 别试图自己编译 zlib 静态链接——
xlnt的 CMake 脚本对自定义路径支持很弱
合并单元格、公式结果、样式信息这些,xlnt 和 libxls 都不默认暴露。真要拿公式值,得自己 eval;要样式就得切进底层 XML 解析——这时候该考虑是不是 Excel 本来就不该当数据库用。









