[C#] CSV 파일을 .NET 데이터 테이블로 읽는 방법

CSV 파일을 System.Data.DataTable기반으로 데이터 테이블을 생성하여 CSV 파일을에로드하는 방법은 무엇입니까?

일반 ADO.net 기능이이를 허용합니까?



답변

다음은 데이터 구조를 사용하여 CSV 데이터를 데이터 테이블에 복사하여 DataTable을 만드는 우수한 클래스입니다.

플랫 파일을위한 이식 가능하고 효율적인 일반 파서

구성하기 쉽고 사용하기 쉽습니다. 나는 당신이 살펴볼 것을 촉구합니다.


답변

OleDb제공자를 사용하고 있습니다. 그러나 숫자 값이있는 행을 읽을 때 텍스트로 처리하려는 경우 문제가 있습니다. 그러나 schema.ini파일 을 만들어서이 문제를 해결할 수 있습니다 . 내가 사용한 방법은 다음과 같습니다.

// 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;
    }
}


답변

Sebastien Lorion의 Csv Reader 를 사용하기로 결정했습니다 .

Jay Riggs 제안도 훌륭한 솔루션이지만 Andrew Rissing의 Generic Parser가 제공 하는 모든 기능이 필요하지는 않았습니다 .

2010 년 10 월 25 일 업데이트

내 프로젝트에서 거의 1 년 반 동안 Sebastien Lorion의 Csv Reader 를 사용한 후 , 잘 구성된 것으로 생각되는 일부 CSV 파일을 구문 분석 할 때 예외가 발생 함을 발견했습니다.

그래서 Andrew Rissing의 Generic Parser로 전환했는데 훨씬 나아진 것 같습니다.

2014 년 9 월 22 일 업데이트

요즘에는 주로이 확장 방법을 사용하여 구분 된 텍스트를 읽습니다.

https://github.com/Core-Techs/Common/blob/master/CoreTechs.Common/Text/DelimitedTextExtensions.cs#L22

https://www.nuget.org/packages/CoreTechs.Common/

2015 년 2 월 20 일 업데이트

예:

var csv = @"Name, Age
Ronnie, 30
Mark, 40
Ace, 50";

TextReader reader = new StringReader(csv);
var table = new DataTable();
using(var it = reader.ReadCsvWithHeader().GetEnumerator())
{

    if (!it.MoveNext()) return;

    foreach (var k in it.Current.Keys)
        table.Columns.Add(k);

    do
    {
        var row = table.NewRow();
        foreach (var k in it.Current.Keys)
            row[k] = it.Current[k];

        table.Rows.Add(row);

    } while (it.MoveNext());
}


답변

이봐 100 % 효과

  public static DataTable ConvertCSVtoDataTable(string strFilePath)
  {
    DataTable dt = new DataTable();
    using (StreamReader sr = new StreamReader(strFilePath))
    {
        string[] headers = sr.ReadLine().Split(',');
        foreach (string header in headers)
        {
            dt.Columns.Add(header);
        }
        while (!sr.EndOfStream)
        {
            string[] rows = sr.ReadLine().Split(',');
            DataRow dr = dt.NewRow();
            for (int i = 0; i < headers.Length; i++)
            {
                dr[i] = rows[i];
            }
            dt.Rows.Add(dr);
        }

    }


    return dt;
   }

CSV 이미지
여기에 이미지 설명을 입력하십시오

가져온 데이터 테이블
여기에 이미지 설명을 입력하십시오


답변

우리는 64 비트 응용 프로그램으로 갈 때까지 항상 Jet.OLEDB 드라이버를 사용했습니다. Microsoft는 64 비트 Jet 드라이버를 출시하지 않았습니다. 다음은 File.ReadAllLines 및 String.Split을 사용하여 CSV 파일을 읽고 구문 분석하고 DataTable을 수동으로로드하는 간단한 솔루션입니다. 위에서 언급했듯이 열 값 중 하나에 쉼표가 포함 된 상황은 처리하지 않습니다. 우리는 주로 사용자 정의 구성 파일을 읽는 데 사용합니다. CSV 파일 사용에 대한 좋은 부분은 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);
}


답변

이것은 내가 사용하는 코드이지만 앱은 net 버전 3.5로 실행해야합니다.

private void txtRead_Click(object sender, EventArgs e)
        {
           // var filename = @"d:\shiptest.txt";

            openFileDialog1.InitialDirectory = "d:\\";
            openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                if (openFileDialog1.FileName != "")
                {
                    var reader = ReadAsLines(openFileDialog1.FileName);

                    var data = new DataTable();

                    //this assume the first record is filled with the column names
                    var headers = reader.First().Split(',');
                    foreach (var header in headers)
                    {
                        data.Columns.Add(header);
                    }

                    var records = reader.Skip(1);
                    foreach (var record in records)
                    {
                        data.Rows.Add(record.Split(','));
                    }

                    dgList.DataSource = data;
                }
            }
        }

        static IEnumerable<string> ReadAsLines(string filename)
        {
            using (StreamReader reader = new StreamReader(filename))
                while (!reader.EndOfStream)
                    yield return reader.ReadLine();
        }


답변

C #에서 Microsoft.VisualBasic.FileIO.TextFieldParser dll을 사용하여 얻을 수 있습니다.

static void Main()
        {
            string csv_file_path=@"C:\Users\Administrator\Desktop\test.csv";

            DataTable csvData = GetDataTabletFromCSVFile(csv_file_path);

            Console.WriteLine("Rows count:" + csvData.Rows.Count);

            Console.ReadLine();
        }


private static DataTable GetDataTabletFromCSVFile(string csv_file_path)
        {
            DataTable csvData = new DataTable();

            try
            {

            using(TextFieldParser csvReader = new TextFieldParser(csv_file_path))
                {
                    csvReader.SetDelimiters(new string[] { "," });
                    csvReader.HasFieldsEnclosedInQuotes = true;
                    string[] colFields = csvReader.ReadFields();
                    foreach (string column in colFields)
                    {
                        DataColumn datecolumn = new DataColumn(column);
                        datecolumn.AllowDBNull = true;
                        csvData.Columns.Add(datecolumn);
                    }

                    while (!csvReader.EndOfData)
                    {
                        string[] fieldData = csvReader.ReadFields();
                        //Making empty value as null
                        for (int i = 0; i < fieldData.Length; i++)
                        {
                            if (fieldData[i] == "")
                            {
                                fieldData[i] = null;
                            }
                        }
                        csvData.Rows.Add(fieldData);
                    }
                }
            }
            catch (Exception ex)
            {
            }
            return csvData;
        }