使用OLEDB命令读取csv

时间:2014-01-22 14:25:40

标签: c#

尝试使用oledb命令读取csv文件。以下是我正在使用。 此代码执行顺利。但是我需要从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;
            }
        }
    }
}

3 个答案:

答案 0 :(得分:2)

我试图开发一种将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;
}

答案 1 :(得分: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();

答案 2 :(得分:0)

没有内置方法告诉OLEDB将第二行用于标题而不是第一行。

您必须打开CSV文件,远程显示第一行,然后再次保存。幸运的是,这很容易做到:

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

(如果您使用的是.NET版本&lt; 4,请在.ToArray()之后添加Skip(1)