xlslib输出UTF8汉字的方法

原版xlslib输出UTF8汉字有误,我在网上找到这个古老的帖子修改开源xlslib使得支持输出UTF8中文Excel文件内容不乱码, 它自定义了2个指定UTF8编码的重载label()函数。
照做后,第一步发现编译有错

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

观察同一个函数的其他重载声明,ustring命名空间不是std而是xlslib_strings,照着改成如下声明后,make通过。在xlslib/xlslib/src/.libs中生成了新的动态链接库文件。

		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 教程网站上找到了std::wstring_convert转换器,写成如下就能正确输出UTF8汉字和数字混合字符串了。

        // 写入标题
        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!";

			// 转换为 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;
        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值