CsvHelper-设置标题行和数据行

问题描述

我有如下示例数据:

 1  This is a random line in the file
 2  
 3  SOURCE_ID|NAME|START_DATE|END_DATE|VALUE_1|VALUE_2
 4
 5  Another random line in the file
 6  
 7  
 8  
 9  
10  GILBER|FRED|2019-JAN-01|2019-JAN-31|ABC|DEF
11  ALEF|ABC|2019-FEB-01|2019-AUG-31|FBC|DGF
12  GILBER|FRED|2019-JAN-01|2019-JAN-31|ABC|TEF
13  FLBER|RED|2019-JUN-01|2019-JUL-31|AJC|DEH
14  GI|JOE|2020-APR-01|2020-DEC-31|GBC|DER

我无法保存对文件的更改。即,我无法在使用前操纵/清理原始文件。任何操作都需要在内存中即时进行。但是,如果文件很大(例如,我目前正在测试一些5m +记录的文件)。

我正在使用CsvHelper

我已经参考以下主题进行指导:

CSVHelper to skip record before header

Better way to skip extraneous lines at the start?

How to read a header from a specific line with CsvHelper?

我想做的是:

  • 设置标头为3的行(我知道标头在哪里)
  • 设置数据从何处开始= 10(我将知道数据从何处开始)
  • 将数据加载到数据表中,以显示在datagridview中

如果在将其传递给CsvHelper之前需要执行流操作的组合,那么还请告知我这是否是缺少的部分吗? (以及有关如何在一个代码块下实际实现该目标的任何帮助,我们将不胜感激)

到目前为止,我已经提出了以下建议:

string filepath = Path.Combine(txtTst04_File_Location.Text,txtTst04_File_Name.Text);

using (var reader = new StreamReader(filepath))
using (var csv = new CsvReader(reader,CultureInfo.InvariantCulture))
{

    // skip rows to get the header
    for (int i = 0; i < 4; i++) 
    {
        csv.Read();
    }

    csv.Configuration.Delimiter = "|"; // Set delimiter
    csv.Configuration.IgnoreBlankLines = false;
    csv.Configuration.HasHeaderRecord = true;
    
    // how do I set the row where the actual data starts? 

    using (var dr = new CsvDataReader(csv))
    {
        var dt = new DataTable();
        dt.Load(dr);
        dgvTst04_View.DataSource = dt; // Set datagridview source to datatable
    }

}

我得到以下结果:

DataGridViewResult

请让我知道您是否希望我在任何时候进行扩展。

谢谢!

编辑:

此处创建的新链接帖子试图解决相同的目标,但以不同的方式,但出现新的错误Filestream and datagridview memory issue with CsvHelper

解决方法

我可以将其与ShouldSkipRecord一起使用。唯一的问题是,如果任何随机行带有“ |”,它将失败。分隔符。

using (var reader = new StreamReader(filepath))
using (var csv = new CsvReader(reader,CultureInfo.InvariantCulture))
{
    csv.Configuration.Delimiter = "|"; // Set delimiter
    csv.Configuration.ShouldSkipRecord = row => row.Length == 1;
    
    using (var dr = new CsvDataReader(csv))
    {
        var dt = new DataTable();
        dt.Load(dr);
        dgvTst04_View.DataSource = dt; // Set datagridview source to datatable
    }

}

如果您知道有多少列,可以将其设置为跳过任何少于该列的行。

csv.Configuration.ShouldSkipRecord = row => row.Length < 6;
,

我想出了另一种方法,允许您跳过到标题的行,然后再跳过记录。

using (var reader = new StreamReader(filepath))
using (var csv = new CsvReader(reader,CultureInfo.InvariantCulture))
{
    csv.Configuration.Delimiter = "|"; // Set delimiter
    csv.Configuration.IgnoreBlankLines = false;

    // skip to header
    for (int i = 0; i < 3; i++)
    {
        csv.Read();
    }

    csv.ReadHeader();

    var headers = csv.Context.HeaderRecord;

    // skip to records
    for (int i = 0; i < 6; i++)
    {
        csv.Read();
    }

    var dt = new DataTable();

    foreach (var header in headers)
    {
        dt.Columns.Add(header);
    }

    while (csv.Read())
    {
        var row = dt.NewRow();
        for (int i = 0; i < headers.Length; i++)
        {
            row[i] = csv.GetField(i);
        }

        dt.Rows.Add(row);
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...