對xlslib庫與libxls庫的簡易封裝


一、簡介

  xlslib庫是用來創建excel文件、libxls是用來讀取excel文件的,在使用C++或者QT語言來設計對excel文件的讀取。都需要事先下載這兩個庫編譯成功后再進行程序設計的。之所以選擇這兩個庫來使用,是因為這兩個庫即可以在windows系統下使用,又可以在Linux系統下使用。對於設計跨平台使用的程序來說這兩個庫是一個不錯的選擇。xlslib源碼生成動(xlslib.dll)/靜(xlslib.lib)態庫的具體的編譯方法,網上有很多資源,再次不在贅述。本文注重介紹libxls庫的生成方法。

二、libxls庫的生成方法

  1、首先下載cygwin,32位操作系統下載setup-x86.exe,64位電腦下載setup-x86_64.exe。


  2、安裝cygwin下的編譯環境
    編譯x86鏈接庫安裝以下組件:
        Devel下的make、mingw64-i686-binutils、mingw64-i686-gcc-core、mingw64-i686-gcc-g++、mingw64-i686-win-iconv

      編譯x64鏈接庫安裝以下組件:
      Devel下的make、mingw64-x86_64-binutils、mingw64-x86_64-gcc-core、mingw64-x86_64-gcc-g++、mingw64-x86_64-win-iconv

  3、下載libxls(1.4.0版本)源碼:

  4、打開cygwin(默認當前路徑為/home/Administrator),使用cd libxls命令將當前文件路徑切換到源碼所在文件夾,執行下面命令進行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

  5、前面步驟正確的話,步驟4中的配置就會成功並生成必須的makefile文件,執行“make && make install”來進行編譯安裝了。

  6、只要make沒報錯,我們就能在$(cygwin_home)/usr/local/libxls下即可看到安裝成果($(cygwin_home)是指cygwin的安裝目錄)。
        安裝成果中的bin目錄只有xls2csv.exe,但是沒法成功運行,原因就如提示一樣:缺少iconv.dll。
        x86:拷貝\usr\i686-w64-mingw32\sys-root\mingw\bin下的iconv.dll;
        x64:拷貝\usr\x86_64-w64-mingw32\sys-root\mingw\bin下的iconv.dll即可正常運行。
        安裝成果中的lib目錄只有libxlsreader.a和libxlsreader.la,並沒有我們需要的dll和lib文件。不過可以利用.a文件最終轉換出運行需要的dll、鏈接需要的lib及def文件。

  7、接下來我們利用安裝成果中的libxlsreader.a來生成我們需要的dll、lib和def文件。
     (1)x86:在cygwin命令行下執行“i686-w64-mingw32-ar x libxlsreader.a”提取a中的.o文件
      x64:在cygwin命令行下執行“x86_64-w64-mingw32-ar x libxlsreader.a”提取a中的.o文件
     (2)然后利用.o文件來生成dll和def文件,具體命令如下:
                  x86:i686-w64-mingw32-gcc -shared -o libxls.dll *.o -Wl,--export-all-symbols,--output-def,libxls.def -liconv
               x64:x86_64-w64-mingw32-gcc -shared -o libxls.dll *.o -Wl,--export-all-symbols,--output-def,libxls.def -liconv
     (3)利用dll和def通過visual studio的lib來得到鏈接需要的lib文件,打開visual studio 命令提示,然后切換目錄到dl所在目錄並執行:
     x86:lib /machine:X86 /def:libxls.def
       x64:lib /machine:X64 /def:libxls.def

  8、至此大功告成,我們得到了x86和x64兩個版本的libxls鏈接庫(dll&lib),而且中文也能正常支持。接下來我們就可以愉快地封裝和使用libxls庫了

三、使用示例

  本程序中我對這兩個庫做了簡易的封裝,生成了兩個動態庫,主要功能就是對excel文件的創建寫入和讀取顯示。

xlslib庫的封裝

createxcel_global.h文件

#ifndef CREATEXCEL_GLOBAL_H
#define CREATEXCEL_GLOBAL_H


#ifdef QEXCEL__API_EXPORTS
# define QEXCEL__API _declspec(dllexport)
#else
# define QEXCEL__API _declspec(dllimport)
#endif

#endif // QEXCEL_GLOBAL_H

createxcel.h文件

#ifndef QEXCEL_H
#define QEXCEL_H

#include "createxcel_global.h"
#include <QString>
#include <sstream>
#include <string>
#include "xlslib.h"
using namespace std;
using namespace xlslib_core;
class QEXCEL__API QEXCEL
{
public:
    QEXCEL();
    ~QEXCEL();

   void CreateWorkSheet(QString SheetName); //創建表格
   void SaveExcelFile(QString FileName);  //保存工作簿
   void SetCellNumber(int row,int col,int number); //設置序號
   void SetCellText(int row,int col,QString text,bool setFont); //設置文本信息
     
   void SetCellSize(int row,int col,int row_width ,int col_hight); //設置單元格大小
   void SetCellCenter(); //設置單元格格式居中
   void SetCellLeft(); //設置單元格格式靠左居中
   void MergeCells(int begin_row,int begin_col,int end_row,int end_col);  //合閉單元格
  // void SetFontSize(int Fontsize);

public:
    // 單元格
    cell_t * cell;
    font_t * _font;
    xf_t * xf;
private:
    // 工作簿
    workbook pWB;
    // 工作表
    worksheet *pWS;
};

#endif // QEXCEL_H

createxcel.cpp文件

#include "createxcel.h"
#include <stdio.h>
#pragma comment(lib, ".\\lib\\xlslib_lib.lib")
QEXCEL::QEXCEL()
{
     
    pWS = NULL;
    cell = NULL;
    _font = NULL;
    xf = NULL;
}

QEXCEL::~QEXCEL()
{

}

void QEXCEL::CreateWorkSheet( QString SheetName )
{
   string sheetname = string((const char *)SheetName.toLocal8Bit());  //Qstring 轉換成String
   pWS = pWB.sheet(sheetname);
   pWS->defaultColwidth(25);  //設置默認列寬
   pWS->defaultRowHeight(15);  //設置默認行高
    _font = pWB.font("Arial");
   _font->SetBoldStyle(BOLDNESS_BOLD);  // 設置粗字體
   _font->SetHeight(220);              //設置字體大小11

   xf = pWB.xformat();
   xf->SetFont(_font);
   xf->SetFillBGColor(CLR_WHITE);
   xf->SetFillFGColor(CLR_RED);
   pWS->MakeActive();
       
}

void QEXCEL::SaveExcelFile( QString FileName )
{
    string filename = string((const char *)FileName.toLocal8Bit());
    pWB.Dump(filename);

}

 

void QEXCEL::SetCellText( int row,int col,QString text,bool setFont )
{
    
    string value = string((const char *)text.toLocal8Bit());
    //xlslib_strings::ustring value = text.toStdWString();
     
    if (setFont == true)   //顯示為粗體
    {
        cell = pWS->label(row, col,value/* L"中國"*/,xf); 
    }
    else
    {
        cell = pWS->label(row, col, value,NULL);
    }
    
     
}

void QEXCEL::SetCellNumber( int row,int col,int number )
{
    stringstream oss;
    string Num;
    oss << number;
    oss >> Num;        
   cell = pWS->label(row, col, Num,NULL);
}

void QEXCEL::SetCellSize( int row,int col,int row_width ,int col_hight )
{
    if(row_width!=0)
    {
        pWS->rowheight(row,row_width);
    }

    if (col_hight!=0)
    {
        pWS->colwidth(col,col_hight);
    }
}

void QEXCEL::SetCellCenter()
{
    cell->halign(HALIGN_CENTER);   //單元格水平方向居中
    cell->valign(VALIGN_CENTER);  //單元格垂直方向居中

}

void QEXCEL::SetCellLeft()
{
    cell->halign(HALIGN_LEFT);  //單元格水平方向靠左
    cell->valign(VALIGN_CENTER);
}

void QEXCEL::MergeCells( int begin_row,int begin_col,int end_row,int end_col )
{
    pWS->merge(begin_row,begin_col,end_row,end_col);  //合並單元格

}


 

libxls庫的封裝

readexcel_global.h 文件

#ifndef QLIBCOMMON_GLOBAL_H
#define QLIBCOMMON_GLOBAL_H
#ifdef QLibCommon_API_EXPORTS
#define QLibCommon_API _declspec(dllexport)
#else
#define QLibCommon_API _declspec(dllimport)
#endif

#endif // QLIBCOMMON_GLOBAL_H

ReadExcel.h 文件

#ifndef CSKQEXCELCOMMOM_H
#define CSKQEXCELCOMMOM_H

#include "readexcel_global.h"
 
#include <QString>
 
#include "xls.h"
using namespace xls;
class QLibCommon_API ReadExcel
{
public:
    ReadExcel(QString strpath);
    ~ReadExcel();
    // 工作簿
    xlsWorkBook* getworkbooks();

    // 工作表
    xlsWorkSheet* selectSheet(int sheetIndex);
     
    //獲取工作表數量
    int getSheetsCount();

    //獲取工作表名稱
    QString getSheetName(int sheetIndex);

    //獲取工作表單元格內容
    QString getCellValue(int row, int column);

    //獲取單元表行數
    int getUsedRowsCount();

    //獲取單元表列數
    int getUsedColsCount();

    //關閉工作表
    void closeSheet();

    //關閉工作簿
    void closeWorkBook();
private:
    // 工作簿
    xlsWorkBook *pWB;
    // 工作表
    xlsWorkSheet *pWS;
    // 單元格
    xlsCell * cell;

};

#endif // CSKQEXCELCOMMOM_H

ReadExcel.cpp 文件

#include "ReadExcel.h"
#pragma comment(lib, ".\\lib\\libxls.lib")

ReadExcel::ReadExcel( QString strpath )
{
    pWB = NULL;
    pWS = NULL;
    cell = NULL;
    ///qstring轉換為const char */////////
    //方法一
        std::string str = strpath.toStdString();
        const char* path = str.c_str();
    //方法2
//     const char* path;
//     QByteArray ba = strpath.toLatin1();    
//     path=ba.data();

    //////////////////////
    pWB = xls_open(path, "GBK");
    if (!pWB)
    {
        printf("Open File Error! pWB\n"/*,pWB*/);
    
        return ;

    }
    else
    {
        xls_parseWorkBook(pWB);
    }
}

ReadExcel::~ReadExcel()
{

}

xlsWorkBook* ReadExcel::getworkbooks()
{
   return pWB;
}

xlsWorkSheet* ReadExcel::selectSheet(int sheetIndex)
{
// 獲取工作表(第幾個工作表)
   pWS = xls_getWorkSheet(pWB,sheetIndex);
// 解析工作表
   xls_parseWorkSheet(pWS);
   return pWS;
}

int ReadExcel::getSheetsCount()
{
    return pWB->sheets.count;
}

QString ReadExcel::getSheetName( int sheetIndex )
{
  return (char *)pWB->sheets.sheet[sheetIndex].name;
}

QString ReadExcel::getCellValue( int row, int column )
{
    cell = xls_cell(pWS, row-1, column-1); //行列起始號為1
    // 判斷單元格及內容是否為空
    if (cell && cell->str)
    {
        return (char *)cell->str;    
    }
}

int ReadExcel::getUsedRowsCount()
{
  return pWS->rows.lastrow;
}

int ReadExcel::getUsedColsCount()
{
  return pWS->rows.lastcol;
}

void ReadExcel::closeSheet()
{
    //關閉表格
    xls_close_WS(pWS);
    cell = NULL;
    pWS = NULL;
   
   
}

void ReadExcel::closeWorkBook()
{
    // 關閉工作簿
    xls_close_WB(pWB);
    pWB = NULL;

}

 


免責聲明!

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



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