做个项目需要读取xls文件,通过搜索,找到三个库,BasicExcel、libxl、libxls。
因为BasicExcel不支持中文,而且06年就没更新了,果断放弃。libxl感觉是这三个库中最好的,能读能写,对格式支持也最好,但是考虑到项目只需要读取,而且这是商业软件,授权也不便宜,也放弃了。
首先下载libxls,项目地址:http://sourceforge.net/projects/libxls/,备用下载:libxls-1.4.0.zip
解压后使用:
./configure --prefix=/usr make sudo make install
安装,请注意,在configure前,一定要安装libiconv-dev,否则中文显示可能不正常。
Fedora下: yum install libiconv-devel Mingw下: mingw-get install libiconv
安装后,编写测试代码:
#include <stdio.h> #include <xls.h> // 要打开的文件名 const char fileName[] = "data/1.xls"; // 所有通过libxls库获取的字符串的编码 const char charSet[] = "UTF-8"; // C++必须加这个,否则编译报错 using namespace xls; void testLibxls() { // 工作簿 xlsWorkBook *pWB = NULL; // 工作表 xlsWorkSheet *pWS = NULL; // 单元格 xlsCell * cell = NULL; int sheetIndex; int row, col; // 打开文件 pWB = xls_open(fileName, charSet); if (!pWB) { fprintf(stderr, "Open File Error!\n"); return ; } // 解析xls文件,这个不要忘了 xls_parseWorkBook(pWB); fprintf(stderr, "Sheet count:%d\n", pWB->sheets.count); // 读取每个工作表 for (sheetIndex = 0; sheetIndex < pWB->sheets.count; ++sheetIndex) { // 获取工作表 pWS = xls_getWorkSheet(pWB, sheetIndex); // 解析工作表 xls_parseWorkSheet(pWS); fprintf(stderr, "Sheet %d name: %s\n", sheetIndex, (char *)pWB->sheets.sheet[sheetIndex].name); fprintf(stderr, "Sheet Data:\n"); // 每行 for (row = 0; row < pWS->rows.lastrow; ++row) { // 该行第几列 for (col = 0; col < pWS->rows.lastcol; ++col) { // 获取单元格,这里也可以通过xls_row获取到这行的数据,然后,使用row->cells来获取单元格 cell = xls_cell(pWS, row, col); // 判断单元格及内容是否为空 if (cell && cell->str) { fprintf(stderr, "%s", (char *)cell->str); } fprintf(stderr, ","); } fprintf(stderr, "\n"); } fprintf(stderr, "\n"); // 关闭工作表 xls_close_WS(pWS); } // 关闭工作簿 xls_close_WB(pWB); } int main() { fprintf(stderr, "testLibxls\n"); testLibxls(); getchar(); return 0; }
编译命令
g++ -o main main.cpp -lxlsreader -I/usr/include -L/usr/lib -liconv -static
libxls函数说明:
// 获取libxls版本号 extern const char* xls_getVersion(void); // 设置libxls调试信息,debug>0会显示libxls的调试信息 extern int xls(int debug); // Set debug. Force library to load? // 这个没有研究,不知道干嘛的,感觉像是自定义解析excel的公式 extern void xls_set_formula_hander(xls_formula_handler handler); // 解析工作簿 extern void xls_parseWorkBook(xlsWorkBook* pWB); // 解析工作表 extern void xls_parseWorkSheet(xlsWorkSheet* pWS); // 打开工作簿,charset默认UTF-8 extern xlsWorkBook* xls_open(const char *file,const char *charset); // 关闭工作簿 #define xls_close xls_close_WB // historical extern void xls_close_WB(xlsWorkBook* pWB); // preferred name // 获取工作表 extern xlsWorkSheet * xls_getWorkSheet(xlsWorkBook* pWB,int num); // 关闭工作表 extern void xls_close_WS(xlsWorkSheet* pWS); // 获取工作簿信息,作者啊之类的 extern xlsSummaryInfo *xls_summaryInfo(xlsWorkBook* pWB); // 关闭工作簿信息 extern void xls_close_summaryInfo(xlsSummaryInfo *pSI); // 获取工作表某行 xlsRow *xls_row(xlsWorkSheet* pWS, WORD cellRow); // 获取某个单元格,从参数可以看出,libxls最大支持65536行、65536列的工作表 xlsCell *xls_cell(xlsWorkSheet* pWS, WORD cellRow, WORD cellCol);
合并单元格
通过查看libxls的代码可以发现,libxls对于合并单元格的信息保存在xlsCell中,其中str是内容,colspan>0表示横向合并多少个单元格,rowspan表示纵向合并多少个单元格,被合并的单元格isHidden都是1。