【问题标题】:Reading .txt file content to DataTable with Column headers on first line在第一行使用列标题将 .txt 文件内容读取到 DataTable
【发布时间】:2018-11-02 18:01:48
【问题描述】:

我正在尝试从如下所示的.txt 文件加载数据:

|ABC|DEF|GHI|
|111|222|333|
|444|555|666|

带代码:

using (StringReader reader = new StringReader(new StreamReader(fileStream, Encoding.Default).ReadToEnd()))
{
    string line;
    //reader.ReadLine(); //skip first line
    while (reader.Peek() != -1)
    {
        line = reader.ReadLine();
        if (line == null || line.Length == 0)
            continue;

        string[] values = line.Split('|').Skip(1).ToArray();

        if (!isColumnCreated)
        {
            for (int i = 0; i < values.Count(); i++)
            {
                table.Columns.Add(values[i]);
            }
            isColumnCreated = true;
        }

        DataRow row = table.NewRow();

        for (int i = 0; i < values.Count(); i++)
        {
            row[i] = values[i];
        }
        table.Rows.Add(row);
        products++;
    }
}

问题是,当我生成DataTable 时,我将第一行作为列,但第一行:

|ABC|DEF|GHI|

在行中也可见:

如何将第一行作为列标题,其余作为行?

如果可能的话,我不想使用CSVHelper

【问题讨论】:

  • 你是如何保存到数据库的?

标签: c# winforms datagridview datatable


【解决方案1】:

只需要在创建标题后的第一行时跳过

string line;
bool bheader= false;
                    //reader.ReadLine(); //skip first line
                    while (reader.Peek() != -1)
                    {

                        line = reader.ReadLine();
                        if (line == null || line.Length == 0)
                            continue;

                        string[] values = line.Split('|').Skip(1).ToArray();


                        if (!isColumnCreated)
                        {

                            for (int i = 0; i < values.Count(); i++)
                            {
                                table.Columns.Add(values[i]);
                            }
                            isColumnCreated = true;
                            bheader = true;
                        }
if(bheader ==false){
                        DataRow row = table.NewRow();

                        for (int i = 0; i < values.Count(); i++)
                        {
                            row[i] = values[i];

                        }
                        table.Rows.Add(row);
                        products++;
                    }
                    }
                    bheader = false;
                }

【讨论】:

    【解决方案2】:

    您当前代码的问题是您在 isColumnCreated 为 false 但不是 true 时进行处理。如果你改变这个:

                        if (!isColumnCreated)
                        {
    
                            for (int i = 0; i < values.Count(); i++)
                            {
                                table.Columns.Add(values[i]);
                            }
                            isColumnCreated = true;
                        }
    
                        DataRow row = table.NewRow();
    
                        for (int i = 0; i < values.Count(); i++)
                        {
                            row[i] = values[i];
    
                        }
                        table.Rows.Add(row);
                        products++;
    

    到这里

                        if (!isColumnCreated)
                        {
    
                            for (int i = 0; i < values.Count(); i++)
                            {
                                table.Columns.Add(values[i]);
                            }
                            isColumnCreated = true;
                        }
    
                        DataRow row = table.NewRow();
                        else if (isColumnCreated)
                        {
                             for (int i = 0; i < values.Count(); i++)
                             {
                                   row[i] = values[i];
    
                             }
                             table.Rows.Add(row);
                        }
    

    它应该可以正常工作。如果仅在已创建列标题的情况下创建一行,则您正在创建一种情况,即仅在第一次通过时您才对第一行执行任何操作,然后将其转储。

    【讨论】:

      【解决方案3】:

      我想你想添加列或添加一行。

      if (!isColumnCreated)
      {
      
        for (int i = 0; i < values.Count(); i++)
        {
         table.Columns.Add(values[i]);
         }
         isColumnCreated = true;
         }
       }
      else
      {
        DataRow row = table.NewRow();
      
        for (int i = 0; i < values.Count(); i++)
        {
        row[i] = values[i];
      
        }
        table.Rows.Add(row);
      }
      

      【讨论】:

        【解决方案4】:

        这样就可以了

                DataTable dt = new DataTable();
                using (System.IO.StreamReader sr = new System.IO.StreamReader("PathToFile"))
                {
                    string currentline = string.Empty;
                    bool doneHeader = false;
                    while ((currentline = sr.ReadLine()) != null)
                    {
                        if (!doneHeader)
                        {
                            foreach (string item in currentline.Split('YourDelimiter'))
                            {
                                dt.Columns.Add(item);
                            }
                            doneHeader = true;
                            continue;
                        }
                        dt.Rows.Add();
                        int colCount = 0;
                        foreach (string item in currentline.Split('YourDelimiter'))
                        {
                            dt.Rows[dt.Rows.Count - 1][colCount] = item;
                            colCount++;
                        }
                    }
                }
        

        【讨论】:

          【解决方案5】:

          另一种方法,更面向LINQ

          • 使用File.ReadAllLines 将所有文件行解析为字符串数组。
          • 创建一个包含所有数据行的List&lt;string[]&gt;
            列值由splitting 使用字符串行组成 提供Delimiter.
          • 第一行值用于构建DataTable Columns 元素。
          • 第一行已从列表中删除。
          • 所有其他行都添加到 DataTable.Rows 集合中。
          • DataGridView.DataSource 设置为新的DataTable


          char Delimiter = '|';
          string[] Lines = File.ReadAllLines("[SomeFilePath]", Encoding.Default);
          List<string[]> FileRows = Lines.Select(line => 
              line.Split(new[] { Delimiter }, StringSplitOptions.RemoveEmptyEntries)).ToList();
          
          DataTable dt = new DataTable();
          dt.Columns.AddRange(FileRows[0].Select(col => new DataColumn() { ColumnName = col }).ToArray());
          
          FileRows.RemoveAt(0);
          FileRows.ForEach(row => dt.Rows.Add(row));
          
          dataGridView1.DataSource = dt;
          

          【讨论】:

            猜你喜欢
            • 2015-04-26
            • 2017-02-12
            • 1970-01-01
            • 2021-01-26
            • 2020-08-25
            • 1970-01-01
            • 2012-04-30
            • 1970-01-01
            • 2019-02-25
            相关资源
            最近更新 更多