Get CSV file header using apache commons
Asked Answered
H

7

19

I have been looking for the past 2 hours for a solution to my problem in vain. I'am trying to read a CSV File using Apache commons ,I am able to read the whole file but my problem is how to extract only the header of the CSV in an array?

Hurlburt answered 28/3, 2016 at 19:13 Comment(0)
C
7

By default, first record read by CSVParser will always be a header record, e.g. in the below example:

CSVFormat csvFileFormat = CSVFormat.DEFAULT.withHeader(FILE_HEADER_MAPPING);
FileReader fileReader = new FileReader("file");
CSVParser csvFileParser = new CSVParser(fileReader, csvFileFormat);
List csvRecords = csvFileParser.getRecords();

csvRecords.get(0) will return the header record.

Cyte answered 28/3, 2016 at 19:25 Comment(2)
This is an impossible answer. It appears to have been cribbed from examples.javacodegeeks.com/core-java/apache/commons/csv-commons/…. Note that FILE_HEADER_MAPPING contains the header.. which is what the original question was asking for.Board
As @Board was pointing out, the answer does not address the original question as the code provided assumes that the header fields are already available in FILE_HEADER_MAPPING. I downvoted so better answers can bubble to the top.Audrit
P
10

I looked everywhere and even the solution above didn't work. For anyone else with this issue, this does.

Iterable<CSVRecord> records;
Reader in = new FileReader(fileLocation);
records = CSVFormat.EXCEL.withHeader().withSkipHeaderRecord(false).parse(in);
Set<String> headers = records.iterator().next().toMap().keySet();

Note that your use of .next() has consumed one row of the CSV.

Phago answered 12/3, 2019 at 20:45 Comment(0)
A
8

Since Apache Commons CSV v1.9.0, the withSkipHeaderRecord() & the withFirstRecordAsHeader() methods are deprecated. A builder interface is provided. Use it thusly:

CSVFormat.DEFAULT.builder()
    .setHeader()
    .setSkipHeaderRecord(true)
    .build();
Addendum answered 12/4, 2022 at 21:34 Comment(1)
This is a good answer, but not complete. It sent me looking for more. I think you should add something likeReader in = new FileReader(fileName, StandardCharsets.UTF_8); and CSVFormat cSVFormat = CSVFormat.DEFAULT.builder().setHeader().setSkipHeaderRecord(false).build(); and Iterable<CSVRecord> records = CSVParser.parse(in, cSVFormat);Monarch
C
7

By default, first record read by CSVParser will always be a header record, e.g. in the below example:

CSVFormat csvFileFormat = CSVFormat.DEFAULT.withHeader(FILE_HEADER_MAPPING);
FileReader fileReader = new FileReader("file");
CSVParser csvFileParser = new CSVParser(fileReader, csvFileFormat);
List csvRecords = csvFileParser.getRecords();

csvRecords.get(0) will return the header record.

Cyte answered 28/3, 2016 at 19:25 Comment(2)
This is an impossible answer. It appears to have been cribbed from examples.javacodegeeks.com/core-java/apache/commons/csv-commons/…. Note that FILE_HEADER_MAPPING contains the header.. which is what the original question was asking for.Board
As @Board was pointing out, the answer does not address the original question as the code provided assumes that the header fields are already available in FILE_HEADER_MAPPING. I downvoted so better answers can bubble to the top.Audrit
H
6
BufferedReader br = new BufferedReader(new FileReader(filename));

CSVParser parser = CSVParser.parse(br, CSVFormat.EXCEL.withFirstRecordAsHeader());

List<String> headers = parser.getHeaderNames();

This worked for me. The last line is what you need, extracts the headers found by the parser into a List of Strings.

Harneen answered 7/8, 2019 at 3:13 Comment(1)
CSVFormat.EXCEL is not working for me at all. Can you take a look at this and help me. #67965127 @JustinHibernia
A
1

In Kotlin:

val reader = File(path).bufferedReader()
val records = CSVFormat.DEFAULT.withFirstRecordAsHeader()
    .withIgnoreHeaderCase()
    .withTrim()
    .parse(reader)

println(records.headerNames)
Amblyoscope answered 17/5, 2021 at 4:14 Comment(0)
J
0

The code below works for me:

import java.io.FileReader;
import org.apache.commons.csv.*;

public static String[] headersInCSVFile (String csvFilePath) throws IOException {
        //reading file
        CSVFormat csvFileFormat = CSVFormat.DEFAULT;
        FileReader fileReader = new FileReader(csvFilePath);
        CSVParser csvFileParser = new CSVParser(fileReader, csvFileFormat);
        List csvRecords = csvFileParser.getRecords();
        
        //Obtaining first record and splitting that into an array using delimiters and removing unnecessary text
        String[] headers = csvRecords.get(0).toString().split("[,'=\\]\\[]+");
        String[] result = new String[headers.length - 6];
        for (int i = 6; i < headers.length; i++) {
            //.replaceAll("\\s", "") removes spaces
            result[i - 6] = headers[i].replaceAll("\\s", "");
        } 
        return result;
}
Janejanean answered 20/2, 2022 at 5:14 Comment(0)
O
0

I wanted the same answer as the OP. The answers here are technically correct but were not very helpful without a lot of work. Even after reading all of the posted answers, this still took me a while to accomplish what the OP asked. The best answer provided for the OP uses deprecated methods on CSVFormat. What I finally determined was to ignore all of the content and figure this out myself. The key points are that however you arrive there, the header information only appears to be available from the CSVRecord class which can only be obtained when you start iterating through the CSV data.

So (1) define CSVFormat similar to this (I used EXCEL formatting, but you can use something else):

CSVFormat csvFormat = CSVFormat.EXCEL.builder()     //Use Excel CSV formatting
        .setHeader()                                //Get headers from header record
        .setSkipHeaderRecord(false)                 //Do not skip header record
        .build();

How you set up the iteration can be done in a couple of ways and the OP may not want to do it the way I did. What I did was this:

Reader reader = new BufferedReader(new 
FileReader(this.inputFilePathName));
CSVParser csvParser = new CSVParser(reader, csvFormat);
Iterator<CSVRecord> csvIterator = csvParser.iterator();

I then used csvIterator.hasNext() and csvIterator.next() to check for and get the next record (I had a reason not to use a for loop).

and when iterating through the records, (2) grab the header information on the FIRST CSVRecord you find. Use a boolean flag or something to only get this the first iteration. If csvRecord is the variable for your CSV record, you can get the headers into a Set like this:

Set<String> headers = csvRecord.toMap().keySet();

Technically the OP asked for the information in an array. You could at this point convert the set to an array and be done. But even though I also wanted an array, a set worked just fine.

Olomouc answered 27/6 at 17:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.