How to read a CSV file into a .NET Datatable

后端 未结 22 2108
野性不改
野性不改 2020-11-22 05:12

How can I load a CSV file into a System.Data.DataTable, creating the datatable based on the CSV file?

Does the regular ADO.net functionality allow this?

相关标签:
22条回答
  • 2020-11-22 06:11

    I have been using OleDb provider. However, it has problems if you are reading in rows that have numeric values but you want them treated as text. However, you can get around that issue by creating a schema.ini file. Here is my method I used:

    // using System.Data;
    // using System.Data.OleDb;
    // using System.Globalization;
    // using System.IO;
    
    static DataTable GetDataTableFromCsv(string path, bool isFirstRowHeader)
    {
        string header = isFirstRowHeader ? "Yes" : "No";
    
        string pathOnly = Path.GetDirectoryName(path);
        string fileName = Path.GetFileName(path);
    
        string sql = @"SELECT * FROM [" + fileName + "]";
    
        using(OleDbConnection connection = new OleDbConnection(
                  @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly + 
                  ";Extended Properties=\"Text;HDR=" + header + "\""))
        using(OleDbCommand command = new OleDbCommand(sql, connection))
        using(OleDbDataAdapter adapter = new OleDbDataAdapter(command))
        {
            DataTable dataTable = new DataTable();
            dataTable.Locale = CultureInfo.CurrentCulture;
            adapter.Fill(dataTable);
            return dataTable;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 06:12

    The best option I have found, and it resolves issues where you may have different versions of Office installed, and also 32/64-bit issues like Chuck Bevitt mentioned, is FileHelpers.

    It can be added to your project references using NuGet and it provides a one-liner solution:

    CommonEngine.CsvToDataTable(path, "ImportRecord", ',', true);
    
    0 讨论(0)
  • 2020-11-22 06:14

    We always used to use the Jet.OLEDB driver, until we started going to 64 bit applications. Microsoft has not and will not release a 64 bit Jet driver. Here's a simple solution we came up with that uses File.ReadAllLines and String.Split to read and parse the CSV file and manually load a DataTable. As noted above, it DOES NOT handle the situation where one of the column values contains a comma. We use this mostly for reading custom configuration files - the nice part about using CSV files is that we can edit them in Excel.

    string CSVFilePathName = @"C:\test.csv";
    string[] Lines = File.ReadAllLines(CSVFilePathName);
    string[] Fields;
    Fields = Lines[0].Split(new char[] { ',' });
    int Cols = Fields.GetLength(0);
    DataTable dt = new DataTable();
    //1st row must be column names; force lower case to ensure matching later on.
    for (int i = 0; i < Cols; i++)
        dt.Columns.Add(Fields[i].ToLower(), typeof(string));
    DataRow Row;
    for (int i = 1; i < Lines.GetLength(0); i++)
    {
        Fields = Lines[i].Split(new char[] { ',' });
        Row = dt.NewRow();
        for (int f = 0; f < Cols; f++)
            Row[f] = Fields[f];
        dt.Rows.Add(Row);
    }
    
    0 讨论(0)
  • 2020-11-22 06:14

    I use a library called ExcelDataReader, you can find it on NuGet. Be sure to install both ExcelDataReader and the ExcelDataReader.DataSet extension (the latter provides the required AsDataSet method referenced below).

    I encapsulated everything in one function, you can copy it in your code directly. Give it a path to CSV file, it gets you a dataset with one table.

    public static DataSet GetDataSet(string filepath)
    {
       var stream = File.OpenRead(filepath);
    
       try
       {
           var reader = ExcelReaderFactory.CreateCsvReader(stream, new ExcelReaderConfiguration()
           {
               LeaveOpen = false
           });
    
           var result = reader.AsDataSet(new ExcelDataSetConfiguration()
           {
               // Gets or sets a value indicating whether to set the DataColumn.DataType 
               // property in a second pass.
               UseColumnDataType = true,
    
               // Gets or sets a callback to determine whether to include the current sheet
               // in the DataSet. Called once per sheet before ConfigureDataTable.
               FilterSheet = (tableReader, sheetIndex) => true,
    
               // Gets or sets a callback to obtain configuration options for a DataTable. 
               ConfigureDataTable = (tableReader) => new ExcelDataTableConfiguration()
               {
                   // Gets or sets a value indicating the prefix of generated column names.
                   EmptyColumnNamePrefix = "Column",
    
                   // Gets or sets a value indicating whether to use a row from the 
                   // data as column names.
                   UseHeaderRow = true,
    
                   // Gets or sets a callback to determine which row is the header row. 
                   // Only called when UseHeaderRow = true.
                   ReadHeaderRow = (rowReader) =>
                   {
                       // F.ex skip the first row and use the 2nd row as column headers:
                       //rowReader.Read();
                   },
    
                   // Gets or sets a callback to determine whether to include the 
                   // current row in the DataTable.
                   FilterRow = (rowReader) =>
                   {
                       return true;
                   },
    
                   // Gets or sets a callback to determine whether to include the specific
                   // column in the DataTable. Called once per column after reading the 
                   // headers.
                   FilterColumn = (rowReader, columnIndex) =>
                   {
                       return true;
                   }
               }
           });
    
           return result;
       }
       catch (Exception ex)
       {
           return null;
       }
       finally
       {
           stream.Close();
           stream.Dispose();
       }
    }
    
    0 讨论(0)
提交回复
热议问题