Home > Net >  How to write csv file using common-csv lib
How to write csv file using common-csv lib

Time:08-03

I'm using common-csv to write a CSV file from a request body and I'm getting all the records in the same line and with double quotes:

Client Name,Value
"client 1,1.0","client 2,2.0","client 3,53.78","client 4,3.0","client 5555555,4.0","client 6,33.0","client 7,0.0","client 8,8.5"

What I need is:

Client Name, Value
"client 1", 1.0
"client 2", 2.0
"client 3", 53.78 (and so on)

this is the code (partial):

@PostMapping(value = "/v1/csv")
    public ResponseEntity<InputStreamResource> exportCSVV2(@RequestBody ClientDataObjectRequest clientDataObjectRequest){

        String[] csvHeader = {"Client Name","Value"};
        List<List<CompanyChartData>> csvBody = new ArrayList<>();
        csvBody.add(clientDataObjectRequest.getCompanyChartData());

        ByteArrayInputStream byteArrayOutputStream;

        try(
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                CSVPrinter csvPrinter = new CSVPrinter(
                        new PrintWriter(out),
                        CSVFormat.EXCEL.withHeader(csvHeader)
                );
        ) {

            for (List<CompanyChartData> record: csvBody) {
                csvPrinter.printRecord(record);

            }
            csvPrinter.flush();
            byteArrayOutputStream = new ByteArrayInputStream(out.toByteArray());
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        }

        InputStreamResource fileInputStream = new InputStreamResource(byteArrayOutputStream);

        String dateFile = new SimpleDateFormat("MM-dd-yyyy").format(new java.util.Date());
        String timeFile = new SimpleDateFormat("HH-mm").format(new java.util.Date());
        String fileName = clientDataObjectRequest.getMetricName().replace(" ","_")   "_"   dateFile   "T"   timeFile;

        HttpHeaders headers = new HttpHeaders();
        headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="   fileName   ".csv");
        headers.set(HttpHeaders.CONTENT_TYPE, "text/csv");

        return new ResponseEntity<>(
                fileInputStream,
                headers,
                HttpStatus.OK
        );
    }

This code above is generating the response that I do not want. I've tried others stuff like changing the CSVFormat to another standard, also tried using the method "printRecords" instead of "printRecord". I did some research in the documentation but I'm struggling to understand it.

CodePudding user response:

Looking at your code and the result coming from the printRecord method my first guess would be is that your request mapping is incorrect.

According to the documentation of the printRecord method it will:

Prints the given values a single record of delimiter separated values followed by the record separator.

Looking at the code above it's just performing a for loop until there are no more values in the collection before it prints a new line.

for (final Object value : values) {
    print(value);
}
println();

According to the output given above that would mean that List<CompanyChartData> record in your for loop is a list that contains an Object that contains the all values coming from the request instead of a list of objects that contains your key value pairs.

My assumption would be that if you put a System.out.println statement in the for loop or attach a debugger it should it will only print once.

CodePudding user response:

I found out how to change the outcome.
Instead of using this way:

try(
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                CSVPrinter csvPrinter = new CSVPrinter(
                        new PrintWriter(out),
                        CSVFormat.EXCEL.withHeader(csvHeader)
                );
        ) {

            for (List<CompanyChartData> record: csvBody) {
                csvPrinter.printRecord(record);

            }

I changed to this approach:

try(
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                CSVPrinter csvPrinter = new CSVPrinter(
                        new PrintWriter(out),
                        CSVFormat.DEFAULT.withHeader(csvHeader).withQuoteMode(QuoteMode.NON_NUMERIC)
                );
        ) {

            for (CompanyChartData record: csvBody) {
                csvPrinter.printRecord(record.getClientName(), record.getValue());

            }

And the response was

"Client Name","Value"
"client 1",1.0
"client 2",2.0
"client 3",53.78
  • Related