2014-01-22 187 views
0

我試圖使用oledb命令讀取一個csv文件。以下是我正在使用。 此代碼執行順利。但我需要從csv文件中刪除第一行,並將第二行設置爲數據表的列標題。可能嗎?使用OLEDB命令讀取csv

static DataTable ImportCsvFileToDataTable(string filename, string fullPath) 
{ 
    FileInfo file = new FileInfo(fullPath); 

    using (OleDbConnection con = 
       new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"" + 
       file.DirectoryName + "\";Extended Properties='text;HDR=Yes;FMT=Delimited(,)';")) 
    { 
     using (OleDbCommand cmd = new OleDbCommand(string.Format 
            ("SELECT * FROM [{0}]", file.Name), con)) 
     { 
      con.Open(); 

      // Using a DataTable to process the data 
      using (OleDbDataAdapter adp = new OleDbDataAdapter(cmd)) 
      { 
       DataTable tbl = new DataTable(filename); 
       adp.Fill(tbl); 
       return tbl; 
      } 
     } 
    } 
} 

回答

1

我流下了很多血液,試圖開發一種將CSV導入DataTable的完美方法。結果如下。它將第一行解析爲列標題。這種方法適用於Ace OleDB 12,但是在Jet OleDB 4中也不會有問題。

public static DataTable FromCSV(string FilePath, char Delimiter = ',') 
{ 
    DataTable dt = new DataTable(); 
    Dictionary<string, string> props = new Dictionary<string, string>(); 

    if (!File.Exists(FilePath)) 
     return null; 

    if (FilePath.EndsWith(".csv", StringComparison.OrdinalIgnoreCase)) 
    { 
     props["Provider"] = "Microsoft.Ace.OLEDB.12.0"; 
     props["Extended Properties"] = "\"Text;FMT=Delimited\""; 
     props["Data Source"] = Path.GetDirectoryName(FilePath); 
    } 
    else 
     return null; 

    StringBuilder sb = new StringBuilder(); 

    foreach (KeyValuePair<string, string> prop in props) 
    { 
     sb.Append(prop.Key); 
     sb.Append('='); 
     sb.Append(prop.Value); 
     sb.Append(';'); 
    } 

    string connectionString = sb.ToString(); 

    File.Delete(Path.GetDirectoryName(FilePath) + "/schema.ini"); 
    using (StreamWriter sw = new StreamWriter(Path.GetDirectoryName(FilePath) + "/schema.ini", false)) 
    { 
     sw.WriteLine("[" + Path.GetFileName(FilePath) + "]"); 
     sw.WriteLine("Format=Delimited(" + Delimiter + ")"); 
     sw.WriteLine("DecimalSymbol=."); 
     sw.WriteLine("ColNameHeader=True"); 
     sw.WriteLine("MaxScanRows=1"); 
     sw.Close(); 
     sw.Dispose(); 
    } 

    using (OleDbConnection conn = new OleDbConnection(connectionString)) 
    { 
     conn.Open(); 
     OleDbCommand cmd = new OleDbCommand(); 
     cmd.Connection = conn; 
     cmd.CommandText = "SELECT * FROM [" + Path.GetFileName(FilePath) + "] WHERE 1=0"; 
     OleDbDataAdapter da = new OleDbDataAdapter(cmd); 
     da.Fill(dt); 

     using (StreamWriter sw = new StreamWriter(Path.GetDirectoryName(FilePath) + "/schema.ini", true)) 
     { 
      for (int i = 0; i < dt.Columns.Count; i++) 
      { 
       string NewColumnName = dt.Columns[i].ColumnName.Replace(@"""", @""""""); 
       int ColumnNamePosition = NewColumnName.LastIndexOf("#csv.", StringComparison.OrdinalIgnoreCase); 
       if (ColumnNamePosition != -1) 
        NewColumnName = NewColumnName.Substring(ColumnNamePosition + "#csv.".Length); 
       if (NewColumnName.StartsWith("NoName")) 
        NewColumnName = "F" + (i + 1).ToString(); 
       sw.WriteLine("col" + (i + 1).ToString() + "=" + NewColumnName + " Text"); 
      } 
      sw.Close(); 
      sw.Dispose(); 
     } 

     dt.Columns.Clear(); 
     cmd.CommandText = "SELECT * FROM [" + Path.GetFileName(FilePath) + "]"; 
     da = new OleDbDataAdapter(cmd); 
     da.Fill(dt); 
     cmd = null; 
     conn.Close(); 
    } 

    File.Delete(Path.GetDirectoryName(FilePath) + "/schema.ini"); 
    return dt; 
} 
0

也許是這樣的:

tbl.Rows[0].Delete(); 
    DataRow r = tbl.Rows[0]; 
    foreach(DataColumn c in tbl.Columns) 
    { 
     tbl.Columns[c.ColumnName].ColumnName = r[c.ColumnName].ToString(); 

    } 
    tbl.Rows[0].Delete(); 
0

沒有內置的方式告訴OLEDB使用第二排爲標題,而不是第一行。

您必須打開CSV文件,將第一行遠程打開並再次保存。幸運的是,這是很容易做到:

var lines = File.ReadAllLines(oldFileName); 
File.WriteAllLines(newFileName, lines.Skip(1)); 

(如果您使用的是.NET版本< 4. Skip(1)後添加 .ToArray()