CsvHelper icon indicating copy to clipboard operation
CsvHelper copied to clipboard

Empty DataTable when setting HasHeaderRecord = false

Open dmitriy-shleht opened this issue 6 years ago • 17 comments

Hi I'm trying to read the csv, but as soon as I set HasHeaderRecord = false, then I get an empty table. version:12.1.2

1,one,yes,a
2,two,no,b
using (var reader = new StreamReader("d:\\text.txt"))
using (var csv = new CsvReader(reader, new Configuration{ Delimiter=",", Encoding = Encoding.UTF8, HasHeaderRecord = false}))
{
	using (var dr = new CsvDataReader(csv))
	{
		var dt = new DataTable();
		dt.Load(dr);
		//the table is empty
	}
}

dmitriy-shleht avatar Feb 20 '19 21:02 dmitriy-shleht

Same issue here. Any ideas @dmitriy-shleht ?

facundofarias avatar Mar 06 '19 11:03 facundofarias

Looks like currently there is no way to create IDataReader based on csv without header and read first row:

public CsvDataReader(CsvReader csv)
{
    this.csv = csv;

    csv.Read();

    if (csv.Configuration.HasHeaderRecord)
    {
        csv.ReadHeader();
    }
    else
    {
        skipNextRead = true;
    }
}

Alexey-Stolyarov avatar Mar 06 '19 16:03 Alexey-Stolyarov

I'll add this as a feature.

JoshClose avatar Mar 11 '19 03:03 JoshClose

In fact, it doesn't return any rows at all.

https://github.com/JoshClose/CsvHelper/blob/89edc486b51086453bc91e043f0f82789374b829/src/CsvHelper.Tests/DataTableTests/CsvDataReaderTests.cs#L133

twilsonxpert avatar Mar 11 '19 19:03 twilsonxpert

I think the key here is that CsvDataReader.GetSchemaTable() doesn't add any rows if csv.Configuration.HasHeaderRecord is false.

twilsonxpert avatar Mar 11 '19 22:03 twilsonxpert

I am getting the same issue - the table is empty when HasHeaderRecord = false

do you know when a fix for this will be released?

thanks

jack-guide avatar Jun 25 '19 07:06 jack-guide

Also unable to use this lib because of this error. Will have to switch libs if not resolved soon, which is a shame because I really like this one.

Fix incoming?

enmaku avatar Jul 01 '19 18:07 enmaku

Also, returning an empty dataset when a reasonable configuration option is set to false is adequately unexpected behavior that this should definitely be considered a bug. This really isn't a feature request no matter how you spin it. This is a bug and marking it as a feature request deprioritizes work on it unnecessarily.

enmaku avatar Jul 01 '19 18:07 enmaku

For interim, I wrote the following to use the CsvHelper without a header row to return a DataTable. It does create columns with just the index as the name. Open to better solutions until a fix is implemented.

var data = new DataTable();
bool createColumns = true;

using (var reader = new StreamReader(filename))
using (var csv = new CsvReader(reader))
	while (csv.Read())
	{
		if (createColumns)
		{
			for (int i = 0; i < csv.Context.Record.Length; i++)
				data.Columns.Add(i.ToString());
			createColumns = false;
		}

		DataRow row = data.NewRow();
		for (int i = 0; i < csv.Context.Record.Length; i++)
			row[i] = csv.Context.Record[i];
		data.Rows.Add(row);
	}
return data;

chrisculver701 avatar Sep 12 '19 15:09 chrisculver701

Have we got any solution for this??

kmidhunmathew avatar May 06 '20 19:05 kmidhunmathew

I'll add this as a feature.

Any update on this?

kmidhunmathew avatar May 06 '20 19:05 kmidhunmathew

18 months later, still an issue.

FoolishWiseman avatar Aug 15 '20 21:08 FoolishWiseman

Any update on this?

hoangcurious avatar Mar 31 '21 03:03 hoangcurious

For interim, I wrote the following to use the CsvHelper without a header row to return a DataTable. It does create columns with just the index as the name. Open to better solutions until a fix is implemented.

Thank you! I almost gave up switching to a different library when I found your useful comment.

https://www.joelverhagen.com/blog/2020/12/fastest-net-csv-parsers gives a nice overview about many CSV parsers and their performance, but not functional capability.

[..]

  	for (int i = 0; i < csv.Context.Record.Length; i++)

But I had to add "Parser." at 3 places, e.g.: for (int i = 0; i < csv.Context.Parser.Record.Length; i++)

sfst-from-sf avatar Jun 28 '21 11:06 sfst-from-sf

I am just trying to do this: var config = new CsvConfiguration(CultureInfo.InvariantCulture) { HasHeaderRecord = false };

    var reader = new StreamReader(filestream);
    var csv = new CsvReader(reader, config);
    return csv;

Doesn't return anything if the header record is false. This is a showstopper for me, I want to read all the records so the user can tell me which row the header record is on.

philipcj avatar May 31 '22 11:05 philipcj

I have the same problem. Any fix comming?

ronnysolheim avatar Aug 09 '22 07:08 ronnysolheim

I have the same problem. It's a showstopper as well. Any fix? Perhaps a reasonable work around?

kurtnelle avatar Sep 16 '22 23:09 kurtnelle

I can see the PR for this work is still in peer review state. Is there any news on when this may be reviewed @JoshClose ?

dwing73 avatar Apr 18 '23 13:04 dwing73

Hi. I did the following:

public CsvDataReader(CsvReader csv)
{
	this.csv = csv;

	readCountRows = csv.Configuration.ReadCountRows;

	csv.Read();

	if (csv.Configuration.HasHeaderRecord)
	{
		csv.ReadHeader();
	}
	else
	{
		csv.Configuration.HasHeaderRecord = true;
                csv.GenerateHeader();
                skipNextRead = true;
	}
}
public void GenerateHeader()
{
	context.HeaderRecord = new string[context.Record.Length];
	for (int i = 0; i < context.HeaderRecord.Length; i++)
	{
		context.HeaderRecord[i] = $"Column{i+1}";
	}
	ParseNamedIndexes();
}

BDEsoft avatar Nov 27 '23 11:11 BDEsoft

Fixed.

JoshClose avatar Jan 24 '24 22:01 JoshClose