1. 程式人生 > >xlslib操作excel檔案

xlslib操作excel檔案

一、xlslib介紹  xlslib庫是用來建立excel檔案、libxls是用來讀取excel檔案的,在使用C++或者QT語言來設計對excel檔案的讀取。都需要事先下載這兩個庫編譯成功後再進行程式設計的。之所以選擇這兩個庫來使用,是因為這兩個庫即可以在windows系統下使用,又可以在Linux系統下使用。 官網: http://xlslib.sourceforge.net 下載: http://sourceforge.net/projects/xlslib

 二、工程載入  1、載入xlslib_lib和xlslib_dll工程時,提示下面錯誤  xlslib-package-2.5.0\xlslib\xlslib\build\msvc2012\xlslib_dll.vcxproj : error  : 篩選器“Source Files”下已存在專案“..\..\src\xlslib\formula.cpp”。  解決方法:  用記事本開啟編輯xlslib_lib.vcxproj和xlslib_dll.vcxproj  刪除formula.cpp一行,因為有兩行只保留一行就行。  重新開啟xlslib.sln工程沒有錯誤。    三、工程編譯  createDLL工程編譯,此工程用於將xlslib.lib檔案轉換成xlslib.dll檔案。  編譯createDLL,提示下面錯誤  error C2338: <hash_map> is deprecated and will be REMOVED. Please use <unordered_map>. You can define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS to acknowledge that you have received this warning.  解決方法:在工程屬性中增加巨集定義_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS    xlslib_lib和xlslib_dll工程編譯  1 “sheet_notes”前的型別(建構函式有返回型別或是當前型別名稱的非法重定義?) 解決 src/xlslib/note.h 44-47行 struct sheet_notes {  uint16_t sheet_idx uint16_t sheet_notes; } 成員sheet_notes和結構名一樣衝突了 修改成員名unit16_t sheet_notes為uint16_t sheet_notes__只要不衝突就行。 後續用到這個變數的地方也修改,這個編譯的時候會提示的。 note.cpp(342) last_sheet.sheet_notes__ note.cpp(355) sn.sheet_notes__ note.cpp(358) sn.sheet_notes__   2 formula.cpp(917) error C2059 語法錯誤"{" 解決 將function_propertyp = (function_property) {CELLOP_AS_VALUE, A_UNKNOWN}; 修改為 function_property p ={CELLOP_AS_VALUE, A_UNKNOWN}; 去掉 (function_property)   3測試的例子也有錯誤 targets\test\md5.c(464): error C2143: 語法錯誤 : 缺少“;”(在“型別”的前面) 3>..\..\targets\test\md5.c(467): error C2065: “bload”: 未宣告的識別符號 這個是.c語法 後面申明瞭 int bload 將Int bload提到該函式的最前面一行   再次編譯 提示錯誤 char const * __cdecl check_file(char const *,char const *) 這個是由於c檔案匯出函式介面不同 在Target/test/md5.h 將 #if defined(__cplusplus) extern "C"  { #endif #if defined(__cplusplus) } #endif   註釋取消掉

編譯xlslib_dll工程時,提示error LNK1104: 無法開啟檔案“gdi32.lib”。 此類錯誤解決方法參考這篇文章https://www.cnblogs.com/AkazaAkari/p/6145144.html 右鍵專案->屬性->配置屬性->VC++目錄 要修改兩個值: 包含目錄 庫目錄 點選右側的倒三角->點選編輯->雙擊上方的空白編輯區, 包含目錄就追加    C:\Program Files\Microsoft SDKs\Windows\v7.1A;$(IncludePath) 庫目錄追加     C:\Program Files\Microsoft SDKs\Windows\v7.1A\Lib;$(LibraryPath) (注意,因為版本不同,資料夾不一定是v7.1A,主要看這個目錄下的lib目錄當中有沒有我們報錯中提到的庫)比如win10系統下lib和include路徑 包含目錄 C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\um C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\shared C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\winrt 庫目錄 C:\Program Files (x86)\Windows Kits\10\Lib\10.0.14393.0\um\x86

四、使用例項 1、生成xls

#include <string.h>
#include <xlslib/xlslib.h>

using namespace xlslib_core;
using namespace std;

int main (int argc, char *argv[]) {
    workbook wb;
    xf_t* xf = wb.xformat();
    worksheet* ws;
    ws = wb.sheet("sheet1");
    string label = "Hello, World!";
    ws->label(1,2,label,xf);    // 從0開始數,第1行,第2列,即C3
    wb.Dump("workbook.xls");
    return 0;
}

2、設定顏色

#include <string.h>
#include <xlslib/xlslib.h>

using namespace xlslib_core;
using namespace std;

int main (int argc, char *argv[]) {
    workbook wb; 
    font_t * _font = wb.font("Calibri");
    _font->SetBoldStyle(BOLDNESS_BOLD);  // 設定粗字型
    xf_t* xf = wb.xformat();   
    xf->SetFont(_font);
    xf->SetFillBGColor(CLR_WHITE);
    xf->SetFillFGColor(CLR_RED);
    
    worksheet* ws;    
    ws = wb.sheet("sheet1");   
    cell_t * cell;    
    cell = ws->label(1,2,"hello",xf);    // 從0開始數,第1行,第2列,即C3   
    cell = ws->label(2,2,"world");    
    cell->fillfgcolor(CLR_RED);
    cell->fillbgcolor(CLR_WHITE);
    
    range * _range;    
    _range = ws->rangegroup(0,0,1500,100);   // 設定背景為白色
    _range->cellcolor(CLR_WHITE);    
    _range = ws->rangegroup(1,2,2,2);
    _range->cellcolor(CLR_GOLD);       
    wb.Dump("workbook.xls");
    return 0;
}

3、設定列寬

#include <string.h>
#include <xlslib/xlslib.h>

using namespace xlslib_core;
using namespace std;

int main (int argc, char *argv[]) {
    workbook wb;
    worksheet* ws;
    
    ws = wb.sheet("sheet1");
    ws->defaultColwidth(256*10);
    ws->colwidth(2,256*30);
    
    cell_t * cell; 
    cell = ws->label(1,2,"hello",xf);    // 從0開始數,第1行,第2列,即C3
    cell = ws->label(2,2,"world");   
    wb.Dump("workbook.xls");
    return 0;
}

4、輸入中文

int main (int argc, char *argv[]) {
	 workbook wb;
   worksheet* sh = wb.sheet("sheet");
   sh->label(1,1,"test1");
   sh->label(2,1,L"test3中文");//這裡中文使用unicode編碼
   wb.Dump("workbook.xls");
   return 0;
}

五、注意事項 1、用createDLL生成dll檔案時,需要用管理員許可權開啟vs編譯。 2、輸入字串中包含有中文,請使用unicode編碼,否則就會出現亂碼。 3、低於2.5.0版本的xlslib庫,支援中文需要utf-8編碼方式寫入字串,同時需要修改原始碼。

/*
* 在xlslib/src/sheetrec.h中增加如下程式碼
*/
cell_t* label(int code, unsigned16_t row, unsigned16_t col, const std::ustring& strlabel, xf_t* pxformat = NULL);
cell_t* label(int code, unsigned16_t row, unsigned16_t col, const char* strlabel, xf_t* pxformat = NULL);

/*
* 在xlslib/src/sheetrec.cpp中增加如下程式碼
*/
cell_t* worksheet::label(int code, unsigned16_t row, unsigned16_t col, 
                         const ustring& strlabel, xf_t* pxformat)
{
        enum { UTF8, GBK };
        u16string str16;
        label_t* lbl;
        u16string::const_iterator u16begin, u16end;
        ustring::const_iterator ubegin, uend;
        size_t len;
        
        if (code == UTF8) {
                len = strlabel.length();
                str16.reserve(len);
                ubegin = strlabel.begin();
                uend = strlabel.end();
        
                while(ubegin != uend) {
                        unichar_t c;
                        c = *ubegin++;
                        str16.push_back(c);        
                }
                lbl = new label_t(m_GlobalRecords, row, col, str16, pxformat);
                AddCell((cell_t*)lbl);

                return (cell_t*)lbl;
        } else {
                return NULL;
        }
}
cell_t* worksheet::label(int code, unsigned16_t row, unsigned16_t col, 
                         const char* strlabel, xf_t* pxformat)
{
        enum { UTF8, GBK };
        unsigned16_t u16;
        u16string str16;
        label_t* lbl;
        wstring::const_iterator wbegin, wend;
        size_t len;
        
        if (code == UTF8) {
                if (strlabel == NULL) {
                        return NULL;
                } else {
                        len = strlen(strlabel);
                        wchar_t wcs[len+1];
                        mbstowcs(wcs, strlabel, len+1);
                        len = wcslen(wcs);
                        for (int i = 0; i < len; i++) {
                                u16 = wcs[i];
                                str16.push_back(u16);
                        }
                }

                lbl = new label_t(m_GlobalRecords, row, col, str16, pxformat);
                AddCell((cell_t*)lbl);

                return (cell_t*)lbl;
        } else {
                return NULL;
        }
}
例項:
#include <locale.h>
#include "ocilib.h"
#include "xlslib.h"
using namespace xlslib_core;

#define RECORDCOUNT                65536

int main(int argc, char *argv[])
{
        setlocale(LC_ALL, "zh_CN.utf-8");

        enum { UTF8, GBK };
        workbook wb1, wb2;
        worksheet* wb1sh1 = wb1.sheet("Sheet1");
        worksheet* wb2sh1 = wb2.sheet("Sheet1");
        int row = 0, coloumn = 0;

        if (argc != 4) {
                printf("Example: ./demo SID USER PASSWORD/n");
                return 0;
        }

        OCI_Connection* cn;
    OCI_Statement* st;
    OCI_Resultset* rs;

    OCI_Initialize(NULL, NULL, OCI_ENV_DEFAULT);
    cn = OCI_ConnectionCreate(argv[1], argv[2], argv[3], OCI_SESSION_DEFAULT);
    st = OCI_StatementCreate(cn);
    OCI_ExecuteStmt(st, "select * from t_test_a");

    rs = OCI_GetResultset(st);
    while (OCI_FetchNext(rs))
    {
                if (row < RECORDCOUNT) {
                        wb1sh1->label(UTF8, row, coloumn,        OCI_GetString(rs, 1));
                        wb1sh1->label(UTF8, row, coloumn+1,        OCI_GetString(rs, 5));
                        wb1sh1->label(UTF8, row, coloumn+2,        OCI_GetString(rs, 6));
                } else {
                        wb2sh1->label(UTF8, row-RECORDCOUNT, coloumn,        OCI_GetString(rs, 1));
                        wb2sh1->label(UTF8, row-RECORDCOUNT, coloumn+1, OCI_GetString(rs, 5));
                        wb2sh1->label(UTF8, row-RECORDCOUNT, coloumn+2, OCI_GetString(rs, 6));
                }
                printf("/r%d", row+1);
                fflush(stdout);
                row++;
    }
        printf("/n");

        wb1.Dump("./demo1.xls");
        wb2.Dump("./demo2.xls");
    OCI_Cleanup();

    return EXIT_SUCCESS;
}