選單
GSS 技術部落格
在這個園地裡我們將從技術、專案管理、客戶對談面和大家分享我們多年的經驗,希望大家不管是喜歡或是有意見,都可以回饋給我們,讓我們有機會和大家對話並一起成長!
若有任何問題請來信:gss_crm@gss.com.tw
2 分鐘閱讀時間 (478 個字)

c使用 lumenworks framework io 或 aspose 處理csv檔

unsplash-coding024

 什麼是CSV檔案?

逗號分隔值(Comma-Separated Values,CSV,有時也稱為字元分隔值,因為分隔字元也可以不是逗號),其檔案以純文字形式儲存表格資料(數字和文字)。純文字意味著該檔案是一個字元序列,不含必須像二進位數字那樣被解讀的資料。CSV檔案由任意數目的記錄組成,記錄間以某種換行符分隔;每條記錄由欄位組成,欄位間的分隔符是其它字元或字串,最常見的是逗號或制表符。通常,所有記錄都有完全相同的欄位序列。
CSV檔案的格式不存在通用標準,也沒有指定所使用的字元編碼

這就讓我吃了點小苦頭, 原先從專案搬運回PD的程式

輸出的csv是
"ABC","DEF".....
這樣的格式
其目的很簡單就是為了要避免欄位之中有, 或 " 的問題

但是我們偉大的Microsoft Excel 輸出卻是
ABC,DEF


於是考慮到User使用excel 操作之後, 格式會改變
因此我研究了一下,在Ms Excel 標準之下的csv檔輸出格式

[案例]
~  !  @  #  $  %
^  &  *   (    )   _
+  `   -   =   [   ]
;   '    ,   .   /   <
> ?    :   "  {    }

從以上的列表中可以發現,需要處理的char有 , 跟 "
規則其實很簡單
就是當某格欄位裡有,或" 時
則該格會用用""將字串包起來,並且把字串裡的"換成""

EX:
, => ","
" => """" (一個" 等於兩個" 再用"" 包起來.
"" => """"""

有了以上的規則
我們可以很簡單的做出這樣的匯出方法

///
/// 產生內容
///
///
public string GetContent()
{
    string[] dataSort = GetContentArray();
    return string.Join(",", dataSort.Select(s => fixCSVSpecisalChar(s)));
}

private string fixCSVSpecisalChar(string str)
{
    if (str.Contains(@",") || str.Contains(@""""))
    {
        str = @"""" + str.Replace(@"""", @"""""") + @"""";
    }
    return str;
} 

再來說到匯入
就比較麻煩了
因為如果用split(',')
會不好處理類似這樣的案例

 EX:

ABC,"a,",""",""b",DEF

所以我們不要重複造輪子
直接找前人寫的framework使用

首先找到了第一個方案
LumenWorks.Framework.IO

使用visual studio 開發時, 他可以很簡單的從nuget安裝
安裝之後的使用方式也是很簡單,以下是sample

using (var csvReader = new CsvReader(new StreamReader(file.InputStream, System.Text.Encoding.Default)))
{
    //讀取第一行字當作Title.
    var titleLine = csvReader.GetFieldHeaders();
    //依序移動到下一行
    while (csvReader.ReadNextRecord())
    {
        var array = new string[csvReader.Columns.Count];
        csvReader.CopyCurrentRecordTo(array, 0);
    }
} 

後來考慮到授權問題,以及其實本部門有購買不便宜的Aspose ,當然就要用好用滿
以下是Aspose的sample

using Aspose.Cells;
public static IList<string[]> LoadCSV(Stream fileStream, System.Text.Encoding encoding)
{
    TxtLoadOptions loadOptions = new TxtLoadOptions(LoadFormat.CSV);
    loadOptions.ConvertNumericData = false;
    loadOptions.Encoding = encoding;

    IList<string[]> rs = new List<string[]>();
    using (var workbook = new Workbook(fileStream, loadOptions))
    {
        Worksheet sheet = workbook.Worksheets[0];

        object[,] dataArray = sheet.Cells.ExportArray(0, 0, sheet.Cells.MaxDataRow + 1, sheet.Cells.MaxDataColumn + 1);

        for (int i = 0; i <= dataArray.GetLength(0) - 1; i++)
        {
            List<string> cell = new List<string>();
            for (int j = 0; j <= dataArray.GetLength(1) - 1; j++)
            {
                cell.Add(Convert.ToString(dataArray[i, j]));
            }
            rs.Add(cell.ToArray());
        }
    }
    return rs;
} 
var csv = ExcelHandler.LoadCSV(file.InputStream, System.Text.Encoding.Default);
var titleLine = csv.First();
foreach (var array in csv)
{
    if (titleIndex == 0) { titleIndex++; continue; }

} 
使用c 的attribute 來避免寫重複性程式
R語言資料視覺化技巧-facet-多類別資料分析

相關文章

 

評論

尚無評論
已經注冊了? 這裡登入
Guest
2025/07/21, 週一

Captcha 圖像