在最新的工作中,遇到一個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
沒有。