1

Following approach allows to read with skipping header:

Iterable<CSVRecord> records = CSVFormat.EXCEL.withHeader().parse(in);

for (CSVRecord record : records) {
     //here first record is not header
}

How can I read csv since header line inclusively ?

P.S.

approach:

CSVFormat.EXCEL.withHeader().withSkipHeaderRecord(false).parse(in)

doesn't work and has the same behaviour

gstackoverflow
  • 36,709
  • 117
  • 359
  • 710
  • @Berger, I corrected code a bit. Yes - it is actual code now – gstackoverflow Nov 09 '17 at 13:23
  • 2
    **public final class CSVParser implements Iterable, Closeable {** – gstackoverflow Nov 09 '17 at 13:24
  • This won't be an easy task, if you have a look at the `initializeHeader` method that `CSVParser` calls from its constructor, you will see that `nextRecord()` gets called and skips the first line in your case (`format.getHeader()` is an array of size 0 here). See. https://commons.apache.org/proper/commons-csv/apidocs/src-html/org/apache/commons/csv/CSVParser.html . Why do you have this requirement ? – Arnaud Nov 09 '17 at 15:50
  • 1
    @Berger I did workaround and invoked **records.getHeaderMap().keySet()** before loop to get headers. I need to do some additional check before processing. – gstackoverflow Nov 10 '17 at 08:37
  • Okay that seemed to be the best solution. – Arnaud Nov 10 '17 at 08:48

2 Answers2

3

For me the followings all seem to have the header record as the first one (using commons-csv 1.5):

Iterable<CSVRecord> records = CSVFormat.EXCEL.parse(in);
Iterable<CSVRecord> records = CSVFormat.EXCEL.withSkipHeaderRecord().parse(in); //???
Iterable<CSVRecord> records = CSVFormat.EXCEL.withSkipHeaderRecord(false).parse(in); 
Iterable<CSVRecord> records = CSVFormat.EXCEL.withSkipHeaderRecord(true).parse(in); //???

And as you have stated the following does NOT seem to have the header record as the first one:

Iterable<CSVRecord> records = CSVFormat.EXCEL.withHeader().parse(in); //???

It is beyond my understanding why withSkipHeaderRecord() and withSkipHeaderRecord(true) do include the header while withHeader() does not; seems to be the opposite behaviour as to what the method names suggest.

hammerfest
  • 2,203
  • 1
  • 20
  • 43
1

The withHeader() method tells the parser that the file has a header. Perhaps the method name is confusing.

The withFirstRecordAsHeader() method may also be useful.

From the CSVFormat (Apache Commons CSV 1.8 API) JavaDoc page:

Referencing columns safely

If your source contains a header record, you can simplify your code and safely reference columns, by using withHeader(String...) with no arguments:

CSVFormat.EXCEL.withHeader();

This causes the parser to read the first record and use its values as column names. Then, call one of the CSVRecord get method that takes a String column name argument:

String value = record.get("Col1");

This makes your code impervious to changes in column order in the CSV file.

Dovev Hefetz
  • 1,346
  • 14
  • 21