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个项目
        

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

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

     

  接下来编译,会出现两个sheet_notes的错误。sheet_notes 非法重定义,或构造函数不能返回类型。如下图:
    

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

    

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

    

  再编译,还会提示一个 function_property 的错误
    

  修改代码如下:

     

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

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

    

  其中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路径下的头文件

    

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

    

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

    

    

  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是一样的。所以认为重复定义

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

  解决方法:将所有

1 #ifndef __FRAMEWORK__
2 format_t(CGlobalRecords&gRecords, const xlslib_strings::u16string& fmtstr);
3 #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文件夹需要手动新建(任意文件夹都行)。

    

  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(1)) uint16_t WORD_UA;
typedef __declspec(align(1)) uint32_t DWORD_UA;
#else
typedef uint16_t            WORD_UA        __attribute__ ((aligned (1)));    // 2 bytes
typedef uint32_t            DWORD_UA    __attribute__ ((aligned (1)));    // 4 bytes
#endif    /* _WIN32 */
#endif    /* NO_ALIGN */

#endif    /* XLS_TYPES_INC*/

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

    

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

    

    

  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 @1 DATA
    dumpbuf @2
    get_string @3
    ole2_bufread @4
    ole2_close @5
    ole2_fclose @6
    ole2_fopen @7
    ole2_open @8
    ole2_read @9
    ole2_seek @10
    ole2_sopen @11
    unicode_decode @12
    utf8_decode @13
    verbose @14
    xls @15
    xlsConvertBiff @16
    xlsConvertBof @17
    xlsConvertBoundsheet @18
    xlsConvertCol @19
    xlsConvertColinfo @20
    xlsConvertDouble @21
    xlsConvertFont @22
    xlsConvertFormat @23
    xlsConvertFormula @24
    xlsConvertFormulaArray @25
    xlsConvertHeader @26
    xlsConvertMergedcells @27
    xlsConvertPss @28
    xlsConvertRow @29
    xlsConvertSst @30
    xlsConvertWindow @31
    xlsConvertXf5 @32
    xlsConvertXf8 @33
    xlsIntVal @34
    xlsShortVal @35
    xls_addCell @36
    xls_addColinfo @37
    xls_addFont @38
    xls_addFormat @39
    xls_addRow @40
    xls_addSST @41
    xls_addSheet @42
    xls_addXF5 @43
    xls_addXF8 @44
    xls_appendSST @45
    xls_cell @46
    xls_close_WB @47
    xls_close_WS @48
    xls_close_summaryInfo @49
    xls_debug @50 DATA
    xls_dumpSummary @51
    xls_formatColumn @52
    xls_getCSS @53
    xls_getColor @54
    xls_getVersion @55
    xls_getWorkSheet @56
    xls_getfcell @57
    xls_is_bigendian @58
    xls_makeTable @59
    xls_mergedCells @60
    xls_open @61
    xls_parseWorkBook @62
    xls_parseWorkSheet @63
    xls_preparseWorkSheet @64
    xls_row @65
    xls_set_formula_hander @66
    xls_showBOF @67
    xls_showBookInfo @68
    xls_showCell @69
    xls_showColinfo @70
    xls_showFont @71
    xls_showFormat @72
    xls_showROW @73
    xls_showXF @74
    xls_summaryInfo @75

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

原文地址:https://www.cnblogs.com/Meong/p/8279229.html