C#:将可变结构的 CSV 文件读入带有行计数器的数据表中

C#: Reading a variable structured CSV file into a datatable with a row counter

我正在尝试开发一种工具,可以将 CSV 文件导入到数据表中,数据表中的第一列是行计数器。

CSV 文件来自不同的客户,因此具有不同的结构。有些有 header 行;有些有几行 header 行;有些没有 header 行。他们也有不同的专栏。

到目前为止,我有下面的代码。

    public void Import_CSV()
    {
        OpenFileDialog dialog = new OpenFileDialog();
        dialog.Filter = "CSV Files (*.csv)|*.csv";
        bool? result = dialog.ShowDialog();

        if (result ?? false)
        {
            string[] headers;

            string CSVFilePathName = dialog.FileName;

            string delimSelect = cboDelimiter.Items.GetItemAt(cboDelimiter.SelectedIndex).ToString();

            //  If user hasn't selected a delimiter, assume comma
            if (delimSelect == "")
            {
                delimSelect = ",";
            }

            string[] delimiterType = new string[] {cboDelimiter.Items.GetItemAt(cboDelimiter.SelectedIndex).ToString()};

            DataTable dt = new DataTable();

            //  Read first line of file to get number of fields and create columns and column numbers in data table
            using (StreamReader sr1 = new StreamReader(CSVFilePathName))
            {
                headers = sr1.ReadLine().Split(delimiterType, StringSplitOptions.None);

                //dt.Columns.Add("ROW", typeof(int));
                //dt.Columns["ROW"].AutoIncrement = true;
                //dt.Columns["ROW"].AutoIncrementSeed = 1;
                //dt.Columns["ROW"].AutoIncrementStep = 1; 

                int colCount = 1;

                foreach (string header in headers)
                {
                    dt.Columns.Add("C" + colCount.ToString());
                    colCount++;
                }
            }

            using (StreamReader sr = new StreamReader(CSVFilePathName))
            {
                while (!sr.EndOfStream)
                {
                    string[] rows = sr.ReadLine().Split(delimiterType, StringSplitOptions.None);

                     DataRow dr = dt.NewRow();

                    for (int i = 0; i < headers.Length; i++)
                    {

                            dr[i] = rows[i];
                    }

                    dt.Rows.Add(dr);
                }
            }

            dtGrid.ItemsSource = dt.DefaultView;

            txtColCount.Text = dtGrid.Columns.Count.ToString();
            txtRowCount.Text = dtGrid.Items.Count.ToString();
        }
    }

这有效,因为它创建了列 headers(C1、C2....根据 csv 文件中的数量)然后写入行,但我想要在添加行时在最左侧添加一个带有行号的列。在代码中,您可以看到我注释掉了创建 auto-number 列的部分,但我完全不明白行是如何写入数据表的。如果我取消注释该部分,我会收到错误,因为 csv 文件中的第一列试图写入一个 int 字段。我知道您可以指定每一行中的哪个字段可以进入哪一列,但这在这里无济于事,因为此时这些列是未知的。我只需要它能够读取任何文件,无论结构如何,但使用行计数器。

希望这是有道理的。

您在问题中写道,取消注释添加第一列的代码会导致错误。这是因为你的循环:它从 0 开始,但第 0 列是你手动添加的。所以你只需要在你的循环中跳过它,从 1 开始。但是,源数组必须从第 0 个元素开始处理。

所以解决方案是:

首先,取消注释添加代码的行。

然后,在您的循环中,引入一个偏移量以保持第一列不变:

for (int i = 0; i < headers.Length; i++)
{
    dr[i + 1] = rows[i];
}