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相關的接口寫上的吧,可能出於某種原因導致並沒有寫完或者沒有寫好,有時間試試這幾個函數用起來怎么樣。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM