• 对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:拷贝usri686-w64-mingw32sys-rootmingwin下的iconv.dll;
            x64:拷贝usrx86_64-w64-mingw32sys-rootmingwin下的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
    "/*,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;
    
    }
    海阔凭鱼跃,天高任鸟飞。
  • 相关阅读:
    父级display:none获取子元素宽的问题
    获取url参数
    借一例固定菜单栏!!!
    笨蛋!!!
    调用腾讯地图api,在手机端获取用户地理位置。
    遇到的小tip
    复制事件
    跑马灯!!!!的汉子你威武雄壮!!!
    web页面有哪三层构成?分别是什么?
    CentOS 8 手动部署LNMP环境
  • 原文地址:https://www.cnblogs.com/chenshikun/p/6279806.html
Copyright © 2020-2023  润新知