天津企業(yè)網(wǎng)站設(shè)計報價搜索引擎技術(shù)
原版xlslib輸出UTF8漢字有誤,我在網(wǎng)上找到這個古老的帖子修改開源xlslib使得支持輸出UTF8中文Excel文件內(nèi)容不亂碼, 它自定義了2個指定UTF8編碼的重載label()函數(shù)。
照做后,第一步發(fā)現(xiàn)編譯有錯
In file included from ./xlslib.h:53,from xlslib/cbridge.cpp:50:
./xlslib/sheetrec.h:339:72: error: 'ustring' in namespace 'std' does not name a type; did you mean 'wstring'?339 | cell_t* label(int code, unsigned16_t row, unsigned16_t col, const std::ustring& strlabel, xf_t* pxformat = NULL);| ^~~~~~~| wstring
觀察同一個函數(shù)的其他重載聲明,ustring
命名空間不是std
而是xlslib_strings
,照著改成如下聲明后,make通過。在xlslib/xlslib/src/.libs中生成了新的動態(tài)鏈接庫文件。
cell_t* label(unsigned32_t row, unsigned32_t col,const xlslib_strings::ustring& strlabel, xf_t* pxformat = NULL);
/*
* 在xlslib/src/sheetrec.h中增加如下代碼
*/
cell_t* label(int code, unsigned16_t row, unsigned16_t col, const xlslib_strings::ustring& strlabel, xf_t* pxformat = NULL);
直接用ws->label(UTF8,0, col, "Col_中文");
輸出的仍是亂碼。需要在字符串前加L修飾符,指定它是寬字符串才能輸出漢字,但L"Col_漢字" + std::to_string(col)編譯又會報錯。
在https://www.runoob.com/cplusplus/cpp-libs-codecvt.html 教程網(wǎng)站上找到了std::wstring_convert
轉(zhuǎn)換器,寫成如下就能正確輸出UTF8漢字和數(shù)字混合字符串了。
// 寫入標(biāo)題enum { UTF8, GBK };for (int col = 0; col < cols; ++col) {//ws->label(UTF8,0, col, L"Col_中文");std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;// 原始的 UTF-8 字符串//std::string narrow_string = "Hello, World!";// 轉(zhuǎn)換為 UTF-16 寬字符串//std::wstring wide_string = converter.from_bytes(narrow_string);std::wstring wide_string = converter.from_bytes(("Col_漢字" + std::to_string(col)).c_str());ws->label(UTF8,0, col, wide_string);}
為防止原帖不可訪問。將它的改寫代碼抄錄如下,命名空間已修改
/*
* 在xlslib/src/sheetrec.h中增加如下代碼
*/
cell_t* label(int code, unsigned16_t row, unsigned16_t col, const xlslib_strings::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;}
}