libxlsxwriter只能写不能读,读XLSX应选xlnt等库;xlnt易上手,需注意空单元格判断、日期转换、UTF-8编码、公式值默认返回及大文件内存优化。

用 libxlsxwriter 读不了,得换库
libxlsxwriter 只能写不能读,名字里带“writer”就是个提示。真要读 XLSX,得用支持解析 Open XML 格式的库,比如 libxlsxreader(轻量、C 风格)、xlnt(现代 C++、头文件为主)、或者 libxlsxx(较老但稳定)。其中 xlnt 对新手最友好,API 清晰,不依赖 Boost,编译也简单。
xlnt 的基本读取流程和常见报错
装好 xlnt 后(推荐用 vcpkg:vcpkg install xlnt),读一个表最简路径是:打开工作簿 → 获取活动工作表 → 遍历行 → 提取单元格值。容易卡住的地方有三个:
-
xlnt::workbook wb;构造后不能直接load(),得用xlnt::workbook wb("data.xlsx");或先调wb.load("data.xlsx") - 读空单元格会返回
xlnt::cell_t::empty类型,直接调cell.value()会抛std::runtime_error,必须先用cell.data_type() == xlnt::cell_type::string判断 - 日期类型默认以 Excel 序数(如 44197)返回,不是
std::chrono::time_point,需手动转:用xlnt::date_from_excel_serial()
处理中文乱码和公式结果
XLSX 本身用 UTF-8 存文本,但如果你看到中文变问号或方块,大概率是终端或 IDE 控制台没设 UTF-8 编码(Windows CMD 默认 GBK),跟库无关。公式单元格(如 =SUM(A1:A10))默认返回计算后的值,不是公式字符串——这是对的,除非你明确要源公式,才需 cell.formula();但注意,xlnt 目前不解析公式逻辑,只返回原始字符串。
性能和大文件注意事项
xlnt 加载时会把整个 XLSX 解压进内存并构建 DOM 树,10MB 以上文件就明显变慢,50MB+ 容易 OOM。如果只读某几列或某几行,别用 ws.range("A1:Z1000") 全量加载,改用迭代器方式逐行扫:for (const auto& row : ws.rows()),再检查 row.row_index() 范围跳过无关行。另外,关闭样式解析能提速约 30%:xlnt::workbook wb; wb.load("big.xlsx", xlnt::load_options{}.skip_style(true));
立即学习“C++免费学习笔记(深入)”;
真正麻烦的是合并单元格和自定义数字格式——这些信息存在样式表里,xlnt 支持读但 API 比较底层,比如合并区域得遍历 ws.merged_ranges(),再手动映射到单元格坐标。这类细节,文档里一笔带过,实际要用就得翻头文件里的注释。


















