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;
}