C#開發小試手----小功能:C#讀取csv檔案——針對兩種不同需求的表頭
阿新 • • 發佈:2019-02-11
在練習過程中先後遇到了以下兩種需求:
- 完整讀取CSV檔案,包括CSV檔案的表頭
- 只讀取CSV檔案內容,表頭自定義新增
針對需求1,程式碼如下:
//*********************************csv2dt----讀取csv表頭方案********************************************************** /// <summary> /// 將Csv讀入DataTable /// </summary> /// <param name="filePath">csv檔案路徑</param> /// <param name="n">表示第n行是欄位title,第n+1行是記錄開始</param> /// <param name="k">可選引數表示最後K行不算記錄預設0</param> public static DataTable csv2dt(string filePath, int n) //這個dt 是個空白的沒有任何行列的DataTable { String csvSplitBy = "(?<=^|,)(\"(?:[^\"]|\"\")*\"|[^,]*)"; StreamReader reader = new StreamReader(filePath, System.Text.Encoding.Default, false); int i = 0, m = 0; reader.Peek(); DataTable dt = new DataTable(); while (reader.Peek() > 0) { m = m + 1; string str = reader.ReadLine(); if (m >= n ) { if (m == n ) //如果是欄位行,則自動加入欄位。 { MatchCollection mcs = Regex.Matches(str, csvSplitBy); foreach (Match mc in mcs) { dt.Columns.Add(mc.Value); //增加列標題 } } else { MatchCollection mcs = Regex.Matches(str, "(?<=^|,)(\"(?:[^\"]|\"\")*\"|[^,]*)");//正則表示式判斷 i = 0; System.Data.DataRow dr = dt.NewRow(); foreach (Match mc in mcs) { dr[i] = mc.Value; //dr[i] = mc.Value.Replace("\"", "");//數列字串自帶的引號 i++; } dt.Rows.Add(dr); //DataTable 增加一行 } } } return dt; } private void button1_Click(object sender, EventArgs e)//開啟檔案並傳入ArrayList,此處不可以寫返回,返回會報錯 { string str_filePath = Form1.OpenFile();//開啟檔案 if (str_filePath != "")//判斷來的字串是否為“”,因為在選擇檔案時如果點選取消,則會返回str="",測試過用!=null來判斷,但會報錯; { DataTable dt = Form1.csv2dt(@str_filePath, 1); dataGridView1.DataSource = dt;//datatable資料顯示 } }
針對需求2,程式碼如下:
需求2相較於需求1,多了一個CreateDataTableHead方法,同時改變了CSV2dt方法中的引數取值範圍,即可實現//*********************************csv2dt----自定義表頭方案********************************************* public static DataTable CreateDataTableHead(String[] str_DataTableHead)//建立一個空表,並建立表頭 { DataTable dt = new DataTable(); for (int i = 0; i < str_DataTableHead.Length; i++) { dt.Columns.Add(str_DataTableHead[i]); }//遍歷欄位名作為表頭 return dt; } /// <summary> /// 將Csv讀入DataTable /// </summary> /// <param name="filePath">csv檔案路徑</param> /// <param name="n">表示第n行是欄位title,第n+1行是記錄開始</param> /// <param name="k">可選引數表示最後K行不算記錄預設0</param> public static DataTable csv2dt(string filePath, int n, DataTable dt) //這個dt 是個空白的沒有任何行列的DataTable { String csvSplitBy = "(?<=^|,)(\"(?:[^\"]|\"\")*\"|[^,]*)"; StreamReader reader = new StreamReader(filePath, System.Text.Encoding.Default, false); int i = 0, m = 0; reader.Peek(); while (reader.Peek() > 0) { m = m + 1; string str = reader.ReadLine(); if (m >= n + 1) { if (m == n) //如果是欄位行,則自動加入欄位。 { MatchCollection mcs = Regex.Matches(str, csvSplitBy); foreach (Match mc in mcs) { dt.Columns.Add(mc.Value); //增加列標題 } } else { MatchCollection mcs = Regex.Matches(str, "(?<=^|,)(\"(?:[^\"]|\"\")*\"|[^,]*)"); i = 0; System.Data.DataRow dr = dt.NewRow(); foreach (Match mc in mcs) { dr[i] = mc.Value.Replace("\"", "");//數列字串自帶的引號 i++; } dt.Rows.Add(dr); //DataTable 增加一行 } } } return dt; } private void btn_inputFileForm_daogui1_Click(object sender, EventArgs e)//匯入引數檔案 { string str_filePath = daogui.OpenFile();//開啟檔案 if (str_filePath != "")//判斷來的字串是否為“”,因為在選擇檔案時如果點選取消,則會返回str="",測試過用!=null來判斷,但會報錯; { String[] str_DataTableHead_daogui1 = { "A", "B", "C", "D" }; DataTable dt_TableHead_daogui1 = daogui.CreateDataTableHead(str_DataTableHead_daogui1); daogui1_Para_dt = daogui.csv2dt(@str_filePath, 1, dt_TableHead_daogui1);//csv資料轉換進入DataTable ListOfPara listofpara = new ListOfPara(); listofpara.biaoshi_label_para.Text = "導軌";//此句與本功能無關,方便後面呼叫,做一標識 listofpara.Show(); listofpara.dataGridView_ListOfPara.DataSource = daogui1_Para_dt;//datatable資料顯示 listofpara.dataGridView_ListOfPara.ClearSelection(); } }