Linux/Mingw Excel (*.xls)文件读取,使用libxls库

16 4 月

做个项目需要读取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。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注