关于csv格式保存数值型字符串遇到的问题
在最新的工作中,遇到一个csv
保存格式的问题,经过一番搜索后,特此记录下。
问题描述
在一个导出功能中,既有excel
格式导出,也有csv
格式导出,默认导出格式为excel
,但上线后遇到很多版本不兼容问题,解决起来很麻烦,后面改为csv
格式导出,但又遇到了新的问题,那就是保存时,会把所有的内容当做数字来解析,具体表现在这两个方面:
- 当保存的不是数字时,例如:"000002"、"0012306"之类的内容,实际显示的是"2"、"12306"的,前面的0丢失。
- 当保存为较大数值时,当超过11位后,例如:"150000000000",实际是以科学计数法显示,这里的需求是要原样保存。
解决过程
上面两个保存格式的问题,在保存为excel
格式中有遇到过,当时的解决方法是通过设置该单元格的数值格式来解决,具体解决方法如下:
// 设置数字格式化
void COleDispatchDriver::SetNumberFormat(const VARIANT& value)
{
static BYTE params[] = VTS_VARIANT;
InvokeHelper(0xc1, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, params, &value) ;
}
void COleDispatchDriver::SetValue(const VARIANT& value)
{
static BYTE params[] = VTS_VARIANT;
InvokeHelper(0x6, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, params, &value) ;
}
void COleDispatchDriver::GetValue()
{
VARIANT result;
InvokeHelper(0x8, DISPATCH_PROPERTYGET, VT_VARIANT, (void*)&result, NULL);
return result;
}
// 使用时,先把数据取出来,再对单元格进行格式设置,最后将数值设置进去。
COleVariant var = GetValue();
SetNumberFormat(COleVariant("@")); // 按文本格式保留
//SetNumberFormat(COleVariant("0")); // 按整形格式保留
//SetNumberFormat(COleVariant("0.0")); // 按1位小数保留
SetValue(var);
上述操作虽然可以解决问题,但整个过程相当于把数据取出来又重新设置一次,导出速度很慢。改为csv
格式导出后,还是存在上面的问题,而csv
格式本质是以逗号分隔符保存的文件,可以直接编辑,可读性很好,但通过wps
之类的软件打开时,还是会遇到上面的问题,这可怎么办呢?
网上搜索的解决办法
下面以保存内容为 "01234" 为例子:
方法一:保存为:"=01234'"。 《--- 测试不通过。
方法二:在数值型字符串前加上单引号"'",即:"'01234", 测试显示是正常的,但数值前出现了单引号,如下图所示:
双击该单元格,就显示正常了,如下图:
从内容上看,前面是有"'"号,但在点击保存,会提示
保存的文件格式含有不兼容的的功能,是否继续保存?
点击继续保存后又恢复原样。
方法三:使用内置函数实现转换,实际保存为"=T("01234")"。该种方法也可以实现类似方法三的效果。
方法四:前面增加等号,即保存为: ="01234"。打开后的效果完美,
综合上面四种方法,推荐使用方法四。
小结
csv格式无法数值型字符串前面0的问题,可通过在保存时,加上等号,外加双引号包括来达到效果,即 ="XXXX"
形式。
在导出时,excel
有最大行数限制,而csv
没有。