OpenXLSX仅支持.xlsx格式,不支持.xls;依赖xlnt和zlib,需正确链接;写入中文须显式设置系统已安装的中文字体;读大文件应跳过样式或流式解析以避免OOM。

OpenXLSX 不能直接操作 Excel 的 .xls 文件
OpenXLSX 只支持读写 .xlsx(Office Open XML 格式),完全不支持老式 .xls(二进制 BIFF 格式)。如果你拿到的是 .xls 文件,用 OpenXLSX 打开会静默失败或抛出 xlnt::invalid_file_format 类似的错误——它底层依赖的是 xlnt 的解析器,而 xlnt 从不处理 BIFF。
实操建议:
- 先用文件命令确认格式:
file yourfile.xls,若输出含Composite Document File V2,就是真.xls,必须转格式 - 用 LibreOffice 命令行批量转换:
soffice --headless --convert-to xlsx input.xls - 别尝试用 OpenXLSX + libxls 混合桥接——没有官方支持,内存模型和异常传播都不兼容
链接 OpenXLSX 需要同时处理 xlnt 和 zlib
OpenXLSX 是头文件库,但运行时强依赖 xlnt(它自己的 Excel 解析子库)和 zlib(解压/压缩 ZIP 容器)。CMakeLists.txt 里漏掉任一依赖,编译能过,但链接阶段会报一堆未定义引用,比如:
undefined reference to `xlnt::workbook::workbook()' undefined reference to `uncompress'
常见疏漏点:
立即学习“C++免费学习笔记(深入)”;
- 只
find_package(OpenXLSX),没find_package(xlnt)和find_package(ZLIB) - 链接时只加
OpenXLSX::OpenXLSX,漏了xlnt::xlnt和ZLIB::ZLIB - Windows 下用 MSVC + vcpkg 安装时,默认不编译 xlnt 的 shared 版本,得加
vcpkg install xlnt:x64-windows-static并确保 OpenXLSX 编译选项匹配
写入中文内容必须显式设置字体和编码
OpenXLSX 默认使用 Calibri 字体,该字体在多数 Linux/macOS 系统中不含中文 glyph,单元格看似写了字符串,实际 Excel 打开显示为空白或方块。这不是乱码,是字体缺失导致的渲染失败。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
解决方式不是改 locale 或宽字符转换,而是直接嵌入字体声明:
auto wb = xlnt::workbook();
auto ws = wb.create_sheet("Sheet1");
ws.cell("A1").value("你好世界");
ws.cell("A1").font().name("SimSun"); // Windows
// 或 ws.cell("A1").font().name("Noto Sans CJK SC"); // Linux/macOS
wb.save("output.xlsx");
注意:
-
font().name()必须在value()之后调用,顺序反了无效 - 字体名必须是系统已安装字体的精确名称(区分空格、大小写),可用
fc-list :lang=zh查 Linux 字体 - 不设置字体时,
ws.cell("A1").value(L"你好")用宽字符串也没用——OpenXLSX 内部只存 UTF-8 string_view
读取大文件时避免全量加载到内存
OpenXLSX 默认把整个 .xlsx 解压并解析成 DOM 树,10MB 文件可能吃掉 300MB 内存。对日志导出、报表生成等场景极易 OOM。
可行的轻量读法:
- 用
xlnt::workbook::load()后立刻调用ws.rows()迭代,别缓存所有cell对象 - 禁用样式解析:
xlnt::workbook wb; wb.load("big.xlsx", xlnt::load_options::skip_styles); - 如果只需某几列,手动解析
[Content_Types].xml和xl/worksheets/sheet1.xml(ZIP 内路径),用 tinyxml2 流式读——OpenXLSX 不提供 SAX 接口,这是唯一绕过内存爆炸的办法
真正麻烦的从来不是 API 调用,而是你没意识到 .xlsx 本质是个 ZIP 包,而 OpenXLSX 把它当黑盒全吞了。

















