1. 程式人生 > >C#開發小試手----小功能:C#讀取csv檔案——針對兩種不同需求的表頭

C#開發小試手----小功能:C#讀取csv檔案——針對兩種不同需求的表頭

在練習過程中先後遇到了以下兩種需求:

  1. 完整讀取CSV檔案,包括CSV檔案的表頭
  2. 只讀取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,程式碼如下:

//*********************************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();
		}
	}
需求2相較於需求1,多了一個CreateDataTableHead方法,同時改變了CSV2dt方法中的引數取值範圍,即可實現