vs2008中xlslib与libxls库的编译及使用

时间:2023-03-09 00:39:28
vs2008中xlslib与libxls库的编译及使用

  C++用来操作Excel的方法很多,但是涉及到跨平台,同时又要对Excel的读写操作兼顾,而且免费的库,那应该是要用xlslib和libxls了。由于技术比较菜,折腾这个折腾了一个星期了。最开始是使用QtXlsx库,而且这个库对于Qt来说操作不要太方便,但是研究了一下才发现,这个库是基于Qt5写的,而我们还在用Qt484开发,要想把里面的内容改一下适配Qt4,难度和工作量还是挺大的,因此作罢。后又转投QAxObject类对Excel的COM组件进行操作,这种方法倒是实现了,但是COM组件这个是Windows平台特有的,Linux上也是没什么指望了。因此开始研究了xlslib库和xlslib库,xlslib库只能写Excel文件,libxls库只能读Excel文件。关于这两个库的编译及说明网上一大堆,而且库文件本身存在的问题也有。对于xlslib库的使用官网上有比较详尽的Quick Reference Guide,使用起来还挺方便的,因此先写一下xlslib库的详细编译及使用步骤,然后再写一下libxls库的编译及使用步骤,希望对新入门的猿类有所助。

一、xlslib库的编译

  1、首先从网站下载xlsLib库源码,版本为xlslib-package-2.5.0.zip(1.1MB)

    地址:http://sourceforge.net/projects/xlslib/

  2、将文件解压后得到两个文件夹:OpenEXR、xlslib。在xlslib\xlslib\build路径中有各版本的VS编译工程,以VS2008为例,打开工程后得到7个项目
    vs2008中xlslib与libxls库的编译及使用    vs2008中xlslib与libxls库的编译及使用

   其中,xlslib_dll项目编译动态库文件,编译后得到dll和lib文件;
      xlslib_lib项目编译静态库文件,编译后得到lib文件
      xlslib-testC为xlslib库的C语言应用Example
      xlslib-textCPP为xlslib库的C++应用Example

  3、生成xlslib_dll,直接编译会出现很多问题,在错误列表中会提示"xlslib\***.h"的头文件找不到。原因是:头文件目录未包含进来。将头文件路径添加到工程。按如下方法添加:

    vs2008中xlslib与libxls库的编译及使用

  接下来编译,会出现两个sheet_notes的错误。sheet_notes 非法重定义,或构造函数不能返回类型。如下图:
    vs2008中xlslib与libxls库的编译及使用

  这个错误的原因是,结构体sheet_notes的类型名称和变量命令相同了。由于C/C++中,结构体可以有构造函数,所以,这两个名称是不能相同的。编译器会将成员变量当成是构造函数,从而报错。

    vs2008中xlslib与libxls库的编译及使用

  解决办法是,修改其中一个的名字,只要两个不相同就ok。经过搜索发现成员变量sheet_notes被用到只有3次,而结构体被用到很多次。于是,修改成员变量。

    vs2008中xlslib与libxls库的编译及使用

  再编译,还会提示一个 function_property 的错误
    vs2008中xlslib与libxls库的编译及使用

  修改代码如下:

    vs2008中xlslib与libxls库的编译及使用

  再编译,通过,ok。成功生成dll和lib两种库。通过更改以上错误之后,亲试生成静态库,动态库,64位库文件及32位库文件均成功。

  4、测试工程中使用该库。将头文件及库文件分别放入工程中,静态库,动态库及头文件分别放入以下位置

    vs2008中xlslib与libxls库的编译及使用

  其中xlslib目录下分别包含以下文件,
  xlslib\xlslib目录中放入解压出来的源码..\xlslib\xlslib\src\xlslib路径下的头文件
  xlslib\common目录中放入解压出来的源码..\xlslib\xlslib\src\common路径下的头文件,同时将..\xlslib\xlslib\src中的xlslib.h头文件加入到common文件夹中
  xlslib\oledoc目录中放入解压出来源码..\xlslib\xlslib\src\oledoc路径下的头文件

    vs2008中xlslib与libxls库的编译及使用

  5、在工程包含头文件中加入如下路径

    vs2008中xlslib与libxls库的编译及使用

  在工程引用的库文件中加入如下路径及引用

    vs2008中xlslib与libxls库的编译及使用

    vs2008中xlslib与libxls库的编译及使用

  6、编译测试工程,出现“__FRAMEWORK__”相关的错误:error C2535: “xlslib_core::format_t::format_t错误原因:
  QT的工程配置中配置属性C/C++语言将wchar_t视为内置类型“是/否”和xlslib_lib的冲突,所以编译的时候出现错误。如果在QT的设置里面wchar_t视为内置类型由否修改为是,则QString::toStdWstring()无法使用。除非重新编译QT源码。而报错的地方原因是编译器认为Ustring和u16string是一样的。所以认为重复定义

 format_t(CGlobalRecords&gRecords, const xlslib_strings::ustring& fmtstr);
#ifndef __FRAMEWORK__
format_t(CGlobalRecords&gRecords, const xlslib_strings::u16string& fmtstr);
#endif

  解决方法:将所有

 #ifndef __FRAMEWORK__
format_t(CGlobalRecords&gRecords, const xlslib_strings::u16string& fmtstr);
#endif

  全部注释掉。同时将CPP中的定义也注释掉,最后编译通过。

  xlslib库的使用参考链接:https://github.com/LeslieZhu/books/blob/master/share/xlslibRefGuide.pdf

二、libxls库的编译及使用

  1、从网站上下载源码,最新版本libxls-1.4.0.zip

    地址:http://sourceforge.net/projects/libxls/

  2、解压后,在Linux下的安装方法,亲测可行,生成的.a文件和.la文件:
   ./configure
      make
      make install

  在Window下则需要通过mingw编译器先编译成.a文件,然后将.a文件拆开成.o文件,再将.o文件生成.def文件,最后在VS中使用.o文件和.def文件即可生成dll文件和lib文件。

  3、下载安装cygwin软件,在windows上安装,32位机器下载地址https://cygwin.com/setup-x86.exe,64位机器下载地址https://cygwin.com/setup-x86_64.exe。下载完成后,安装cygwin.exe,安装后选择安装以下组件:
      make
      mingw64-i686-binutils
      mingw64-i686-gcc-core
      mingw64-i686-gcc-g++
      mingw64-i686-win-iconv
  4、等待cygwin安装完成后,将libxls源码放到cygwin目录中,cygwin目录为安装时选择的安装路径,选择将源码放入/home/用户名/opt/下,opt文件夹需要手动新建(任意文件夹都行)。

    vs2008中xlslib与libxls库的编译及使用

  5、在libxls的根目录(../home/fbi/opt/libxls)修改configure中的DEFS定义为:
        DEFS=-DHAVE_CONFIG_H -D_GNU_SOURCE
  (用来解决make时候的警告warning: implicit declaration of function 'asprintf' [-Wimplicit-function-declaration]),cd到源文件目录下,然后在cygwin中执行如下命令对configure进行配置:
    32位:CC='i686-w64-mingw32-gcc' ./configure --host=i686-w64-mingw32 --build=i686-w64-mingw32
    64位:CC='x86_64-w64-mingw32-gcc' ./configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32

  6、以上步骤执行后会生成Makefile文件,直接使用make、make intall命令进行编译安装。只要make过程没出错即可在../usr/local/xlslib目录下看到生成的bin、include、lib文件夹,在bin目录中为xls2csv.exe,但是没法成功运行,提示缺少iconv.dll,在usr\i686-w64-mingw32\sys-root\mingw\bin下即可找到,将该文件复制到bin目录下,xls2csv.exe即可正常运行。include文件夹中为调用该库时需要用到的头文件,lib目录下为libxlsreader.a和libxlsreader.la文件,此时需要通过.a文件转换出windows上运行需要用到的dll文件和lib文件以及链接过程中需要用到的def文件。

  7、接下来利用生成的libxlsreader.a来生成需要的dll、lib及def文件。
      32位:在cygwin命令行下执行“i686-w64-mingw32-ar x libxlsreader.a”提取a中的.o文件
      64位:在cygwin命令行下执行“x86_64-w64-mingw32-ar x libxlsreader.a”提取a中的.o文件

  然后利用.o文件来生成dll文件和def文件,具体命令如下:
      32位:i686-w64-mingw32-gcc -shared -o libxls.dll *.o -Wl,--export-all-symbols,--output-def,libxls.def -liconv
      64位:x86_64-w64-mingw32-gcc -shared -o libxls.dll *.o -Wl,--export-all-symbols,--output-def,libxls.def -liconv

  最后利用dll和def通过visual studio的lib来得到链接需要的lib文件,打开visual studio 命令提示,然后cd /d G:\cygwin64\usr\local\libxls\lib切换目录到dll所在目录并执行:
      32位:lib /machine:X86 /def:libxls.def
      64位:lib /machine:X64 /def:libxls.def

  执行完以上步骤后,即可在cygwin64\usr\local\libxls\lib目录下看到生成的lib文件和dll文件,同时在cygwin64\usr\local\libxls\include目录下为调用库时需要包含的头文件。

  以下为注意事项,在编译过程中出可能出现xlstypes.h文件报错,提示__attribute__相关的错误,主要是由于linux和windows系统对数据格式定义目的差异造成,可将xlstypes.h文件修改如下:

    

#ifndef XLS_TYPES_INC
#define XLS_TYPES_INC #include <stdint.h> typedef unsigned char BYTE;
typedef uint16_t WORD;
typedef uint32_t DWORD; #ifdef NO_ALIGN
typedef uint16_t WORD_UA;
typedef uint32_t DWORD_UA;
#else
#ifdef _WIN32
typedef __declspec(align()) uint16_t WORD_UA;
typedef __declspec(align()) uint32_t DWORD_UA;
#else
typedef uint16_t WORD_UA __attribute__ ((aligned ())); // 2 bytes
typedef uint32_t DWORD_UA __attribute__ ((aligned ())); // 4 bytes
#endif /* _WIN32 */
#endif /* NO_ALIGN */ #endif /* XLS_TYPES_INC*/

  8、libxls进行配置到工程中,先将\usr\local\libxls\include文件夹中的头文件放入到新的工程中的include文件夹中,在工程的设置中添加如下附加包含目录:

    vs2008中xlslib与libxls库的编译及使用

  然后将lib文件放入工程目录下的lib文件夹中,并配置附加库目录如下:

    vs2008中xlslib与libxls库的编译及使用

    vs2008中xlslib与libxls库的编译及使用

  9、在工程中添加头文件如下:
    #include "libxls/xlsstruct.h"
    #include "libxls/xls.h"

    using namespace xls;
   务必将xlsstruct.h文件包含在xls.h头文件之前,否则可能报错。

  到这里就结束了xlslib和libxls库的编译和配置了。libxls库的使用并没有相关文档,目前博客中的说明也不是太多,等用用之后总结一下,再重新写篇介绍的博客吧。搞完这个库也参考了不少博客,就不一一列出参考了,感谢他们的无私奉献。

  最后想到一点,在libxls库的xls.h头文件中发现其中只有读Excel的一些函数声明

extern const char* xls_getVersion(void);

extern int xls(int debug);    // Set debug. Force library to load?
extern void xls_set_formula_hander(xls_formula_handler handler); extern void xls_parseWorkBook(xlsWorkBook* pWB);
extern void xls_parseWorkSheet(xlsWorkSheet* pWS); extern xlsWorkBook* xls_open(const char *file,const char *charset); // convert 16bit strings within the spread sheet to this 8-bit encoding (UTF-8 default)
#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); // utility function
xlsRow *xls_row(xlsWorkSheet* pWS, WORD cellRow);
xlsCell *xls_cell(xlsWorkSheet* pWS, WORD cellRow, WORD cellCol);

  但是在libxls.def文件及xls.c文件中却发现还有写Excel的函数

EXPORTS
brdb @ DATA
dumpbuf @
get_string @
ole2_bufread @
ole2_close @
ole2_fclose @
ole2_fopen @
ole2_open @
ole2_read @
ole2_seek @
ole2_sopen @
unicode_decode @
utf8_decode @
verbose @
xls @
xlsConvertBiff @
xlsConvertBof @
xlsConvertBoundsheet @
xlsConvertCol @
xlsConvertColinfo @
xlsConvertDouble @
xlsConvertFont @
xlsConvertFormat @
xlsConvertFormula @
xlsConvertFormulaArray @
xlsConvertHeader @
xlsConvertMergedcells @
xlsConvertPss @
xlsConvertRow @
xlsConvertSst @
xlsConvertWindow @
xlsConvertXf5 @
xlsConvertXf8 @
xlsIntVal @
xlsShortVal @
xls_addCell @
xls_addColinfo @
xls_addFont @
xls_addFormat @
xls_addRow @
xls_addSST @
xls_addSheet @
xls_addXF5 @
xls_addXF8 @
xls_appendSST @
xls_cell @
xls_close_WB @
xls_close_WS @
xls_close_summaryInfo @
xls_debug @ DATA
xls_dumpSummary @
xls_formatColumn @
xls_getCSS @
xls_getColor @
xls_getVersion @
xls_getWorkSheet @
xls_getfcell @
xls_is_bigendian @
xls_makeTable @
xls_mergedCells @
xls_open @
xls_parseWorkBook @
xls_parseWorkSheet @
xls_preparseWorkSheet @
xls_row @
xls_set_formula_hander @
xls_showBOF @
xls_showBookInfo @
xls_showCell @
xls_showColinfo @
xls_showFont @
xls_showFormat @
xls_showROW @
xls_showXF @
xls_summaryInfo @

vs2008中xlslib与libxls库的编译及使用

  猜想一下libxls库的作者应该也是想把操作Excel相关的接口写上的吧,可能出于某种原因导致并没有写完或者没有写好,有时间试试这几个函数用起来怎么样。