libxlsxwriter中文报错问题

news2024/11/25 22:42:07

libxlsxwriter库在windows系统下VS中存在中文输入报错问题。这在小白关于libxlsxwriter的第一篇博客libxlsxwriter初体验里有所阐述。当时小白给出的解决方案是将文件编码修改成不带签名的utf-8。后来在使用中,小白发现这样并没有完全解决问题。有的中文可以正常写入excel表中,有的中文却不能正常写入。这让人感到困惑和挫败。

1 问题原因

在libxlsxwriter初体验中,小白已经分析了,为什么libxlsxwriter库需要使用不带签名的utf-8编码。即由于excel文件中,用于中间解码的xml文件必须使用不带bom的utf-8编码才能正确解析。然而众所周知,windows系统的编码却是需要带bom的utf-8编码。

问题的原因正是由于这两种编码方式的矛盾。经过小白的检索,博客文章cocos2d-x中文显示问题中提到了:

有个叫wva的人遇到过类似问题,他向微软提交了此bug
http://connect.microsoft.com/VisualStudio/feedback/details/341454/compile-error-with-source-file-containing-utf8-strings-in-cjk-system-locale
根据Visual C++ Compiler Team员工的解释:
The compiler when faced with a source file that does not have a BOM the compiler reads ahead a certain distance into the file to see if it can detect any Unicode characters - it specifically looks for UTF-16 and UTF-16BE - if it doesn’t find either then it assumes that it has MBCS. I suspect that in this case that in this case it falls back to MBCS and this is what is causing the problem.
看见了吧,对于那些没有BOM的文件设计就是这样的。从语气上看,他们编译器小组也不打算修改设计。所以呢,在VC上使用“无签名的UTF-8”编码的文件,你就是在抱着一颗不定时炸弹玩耍。因为你永远都不敢确定哪些词能通过编译,哪些不能!

从这段描述中我们可以得知,在visual studio的C++编译器中,对于“无签名的UTF-8”编码的文件,无法确定哪些词能通过编译,而哪些词不能——事实上在小白的实际使用中,三个字的词(大量的中文人名)通常都不能通过编译。

这就给我们使用libxlsxwriter库造成了很大的阴影:不采用“无签名的utf-8”编码的话,在生成excel的过程中无法正确解码,若采用“无签名的utf-8”编码的话,在visual studio中编译时就要面临大量的中文组合可能无法通过编译的困境。

2 解决方案

没法子,此路不通,换一条路走。还是在cocos2d-x中文显示问题一文中,作者提到了“硬编码字符串”。这种方案对“跨平台代码”可能会产生一定的问题,因为硬编码可能就是与平台或编译器深度绑定的。但这对我们解决问题并无影响:我们就是要解决在windows平台上使用libxlsxwriter库自由写入中文的问题。

于是,找一下转码的文章,这里有一篇,也推荐给大家:
C/C++,字符串的UTF-8与GBK(或GB2312)编码转换

利用这里面的转码函数,我们给出以下方案:源文件编码仍然保持默认的GB2312。

/*
 * Example of writing some data to a simple Excel file using libxlsxwriter.
 *
 * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org
 *
 */

#include "xlsxwriter.h"
#include <iostream>
#include <wchar.h>
#include <windows.h>

using std::string;

// 注意这个转换函数对头文件有所要求
string GBKToUTF8(const char* strGBK)
{
	int len = MultiByteToWideChar(CP_ACP, 0, strGBK, -1, NULL, 0);
	wchar_t* wstr = new wchar_t[len + 1];
	memset(wstr, 0, len + 1);
	MultiByteToWideChar(CP_ACP, 0, strGBK, -1, wstr, len);
	len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* str = new char[len + 1];
	memset(str, 0, len + 1);
	WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
	string strTemp = str;
	if (wstr) delete[] wstr;
	if (str) delete[] str;
	return strTemp;
}

int main() {

    lxw_workbook* workbook = workbook_new("hello_world.xlsx");
    lxw_worksheet* worksheet = workbook_add_worksheet(workbook, NULL);

    worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
    worksheet_write_string(worksheet, 0, 2, GBKToUTF8("不出错").data(), NULL);
    worksheet_write_number(worksheet, 1, 0, 123, NULL);

    workbook_close(workbook);

    return 0;
}

生成的结果如下所示:
在这里插入图片描述

虽然说这个解决方案总感觉有点让人觉得不舒服,但是出于实用主义,既然编译器的开发团队不想解决这个问题,那只能靠我们自己去绕路了。
小白还是觉得很好的,总算是找到了一种能自由使用中文的途径。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/336536.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VHDL语言基础-时序逻辑电路-触发器

目录 触发器&#xff1a; D触发器&#xff1a; 触发器的VHDL描述&#xff1a; 触发器的仿真波形如下&#xff1a;​编辑 时钟边沿检测的三种方法&#xff1a; 方法一: 方法二&#xff1a; 方法三&#xff1a; 带有Q非的D触发器&#xff1a; 带有Q非的D触发器的描述&am…

微信小程序 Springboot高校课堂教学管理系统-java

小程序端 学生在小程序端进行注册并且进行登录。 填写自己的个人信息进行注册 登录成功后可以看到有首页、课程资源、测试、互动论坛、我的功能模块。 课程资源学生可以点击想要查看的资源进行观看。 课程分类学生可以按照自己想要的分类进行搜索并且进行观看。 互动论坛可以查…

四种方式的MySQL安装过程 数据库(2)

目录 1. 仓库安装&#xff1a; 1.1 卸载数据库软件&#xff1a; 2. 本地安装&#xff1a; 2.1 卸载数据库软件&#xff1a; 3. 容器安装&#xff1a; 4. 源码安装&#xff1a; 4.1 使用systemctl命令启动进程 1. 仓库安装&#xff1a; &#xff08;1&#xff09;查看版本…

超级详细GitBook和GitLab集成步骤【linux环境】

介绍 本文主要是在 gitlab 上集成 gitbook 实现提交时 gitbook 自动刷新部署 &#xff0c;以及在 linux 环境上搭建 gitlab gitbook,集成 GitLab CI 实现一个企业级或个人的 Wiki 系统 环境准备 1.一台 linux 服务器 2.安装 node 以及 npm 环境 (这里注意 node 环境不要过高 不…

CS反制之批量伪装上线

分析原理&#xff1a; 我们利用Wireshark抓包工具分析一下Cobalt Strike的上线过程是怎么样的 点击木马&#xff0c;主机上线并抓包 查看数据包 可以看到cookie是一串非对称RSA加密类型&#xff0c;需要一个私钥Private Key才能对其进行解密 我们对Cookie解密看看&#xff…

Django框架之系列二

为什么要搭建虚拟环境? 在开发过程中, 当需要使用python的某些工具包/框架时需要联网安装 比如联网安装Django框架django的1.11.11版本 sudo pip install django1.11.11提示&#xff1a;使用如上命令, 会将Django安装到/usr/local/lib/python2.7/dist-packages路径下问题&…

常见的10种网络安全攻击类型

1. DoS 和 DDoS 攻击DoS 是 Denial of Service 的简称&#xff0c;即拒绝服务。单一的 DoS 攻击一般是采用一对一方式的&#xff0c;通过制造并发送大流量无用数据&#xff0c;造成通往被攻击主机的网络拥塞&#xff0c;耗尽其服务资源&#xff0c;致使被攻击主机无法正常和外界…

57 长短期记忆网络(LSTM)【动手学深度学习v2】

57 长短期记忆网络&#xff08;LSTM&#xff09;【动手学深度学习v2】 深度学习学习笔记 学习视频&#xff1a;https://www.bilibili.com/video/BV1JU4y1H7PC/?spm_id_fromautoNext&vd_source75dce036dc8244310435eaf03de4e330 长短期记忆网络&#xff08;LSTM&#xff09…

Element UI框架学习篇(四)

Element UI框架学习篇(四) 1 准备工作 1.0 创建Emp表并插入相应数据的sql语句 /*MySQL数据库*/SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- ---------------------------- -- Table structure for emp -- ---------------------------- DROP TABLE IF EXISTS emp; CRE…

为什么需要内存对齐

内存对齐 为什么需要内存对齐&#xff1f; 平台原因&#xff1a;不是所有的硬件平台都能访问任意内存地址上的任意数据&#xff0c;某些硬件平台只能在某些地址处取某些特定类型的数据&#xff0c;否则抛出硬件异常。为了同一个程序可以在多平台运行&#xff0c;需要内存对齐…

阻塞式队列-生产者消费者模型

1.阻塞队列是什么 阻塞队列是一种特殊的队列. 也遵守 "先进先出" 的原则. 阻塞队列能是一种线程安全的数据结构, 并且具有以下特性: 当队列满的时候, 继续入队列就会阻塞, 直到有其他线程从队列中取走元素.当队列空的时候, 继续出队列也会阻塞, 直到有其他线程往队…

HLNet代码debug记录

昨天跑HLNet的代码&#xff0c;配环境的时候又双叒叕遇到了一些问题&#xff0c;记录一下&#xff1a; 1.error: identifier “AT_CHECK“ is undefined 出现在python setup.py build develop的时候 参照https://blog.csdn.net/sinat_29957455/article/details/113334944 根据报…

如何在腾讯云服务器上安装Jupyter Notebook示例?

Jupyter简介及服务器端安装 首先&#xff0c;服务器端安装Jupyter。 sudo pip3 install jupyterlab&#xff1a; 启动Jupyter服务 # 设置jupyter web的密码jupyter-notebook password# 创建jupyter工作目录mkdir ~/jupyter_workspace# 启动jupyter (两次ctrlc停止服务)jup…

图解LeetCode——剑指 Offer 32 - III. 从上到下打印二叉树 III

一、题目 请实现一个函数按照之字形顺序打印二叉树&#xff0c;即&#xff1a;第一行按照从左到右的顺序打印&#xff0c;第二层按照从右到左的顺序打印&#xff0c;第三行再按照从左到右的顺序打印&#xff0c;其他行以此类推。 二、示例 2.1> 示例1 提示&#xff1a; …

【软件测试】资深测试工程师说:你真的能做好bug分析吗?

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 bug报告&#xff0c…

Revive:从间谍软件进化成银行木马

2022 年 6 月&#xff0c;Cleafy 研究人员发现了一个新的安卓银行木马 Revive。之所以选择 Revive 这个名称&#xff0c;是因为恶意软件为防止停止工作启用的一项功能名为 revive。 Revive 属于持续潜伏的那一类恶意软件&#xff0c;因为它是为特定目标开发和定制的。这种类型…

Python 四种推导式,包含实例演示

嗨害大家好鸭&#xff01;我是小熊猫~ 这次继续来给大家带来python基础内容~ 源码资料电子书:点击此处跳转文末名片获取 Python 推导式 Python 推导式是一种独特的数据处理方式&#xff0c;可以从一个数据序列构建另一个新的数据序列的结构体。 Python 支持各种数据结构的推…

关于进行vue-cli过程中的解决错误的问题

好久没发文章了&#xff0c;直到今天终于开始更新了&#xff0c;最近想进军全端&#xff0c;准备学习下vue&#xff0c;但是这东西真的太难了&#xff0c;我用了一天的时间来解决在配置中遇到的问题&#xff01;主要问题&#xff1a;cnpm文件夹和vue-cli文件夹的位置不对并且vu…

秒杀项目之网关服务限流熔断降级分布式事务

目录一、网关服务限流熔断降级二、Seata--分布式事务2.1 分布式事务基础2.1.1 事务2.1.2 本地事务2.1.3 分布式事务2.1.4 分布式事务场景2.2 分布式事务解决方案2.2.1 全局事务可靠消息服务2.2.2 最大努力通知2.2.3 TCC事事务三、Seata介绍四、 Seata实现分布式事务控制4.1 案例…

【Android】Binder的理解

1.Binder是什么&#xff1f; 对于android而言&#xff0c;是跨进程传输的通道&#xff0c;是封装好的java类&#xff0c;可以直接继承和使用。 从组成、模型来讲&#xff0c;我认为是连接Server层、Client层、ServerManager层的纽带&#xff0c;也是驱动。 2.Binder的基础概…