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?
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.
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.
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();
Reader 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 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.
FILE_HEADER_MAPPING
contains the header.. which is what the original question was asking for. –
Board 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.
In Kotlin:
val reader = File(path).bufferedReader()
val records = CSVFormat.DEFAULT.withFirstRecordAsHeader()
.withIgnoreHeaderCase()
.withTrim()
.parse(reader)
println(records.headerNames)
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;
}
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.
© 2022 - 2024 — McMap. All rights reserved.
FILE_HEADER_MAPPING
contains the header.. which is what the original question was asking for. – Board