pargrng
pargrng

Reputation: 63

How to convert List of Maps to CSV

I need to convert List of Maps to CSV object which should like below

List<Map<String,Object>> maps = new ArrayList<Map<String,Object>>();

maps object contains the value in below format

map 1 :

(header 1, value1)

(header 2, value2)

(header 3, value3)

(header 4, value4)

map 2 :

(header 1, value5)

(header 2, value6)

(header 3, value7)

(header 4, value8)

I am looking for CSV which should like below

header1, header2,header3, header4

value1, value2,value3,value4

value5,value6,value7,value8

I have tried to read the map (key, value) and writing to CSV files, but its writing to the format

header 1, value1

header2, value2

header 3,value3

header4,value4

header1,value5

like this below is the code snippet which I have tried for

(Map<String, Object> map : maps) {

 for (Map.Entry<String, Object> entry : map.entrySet()) {

w.append(entry.getKey()).append(",").append(entry.getValue()‌​.toString()).append(‌​"\n"); } } 

Upvotes: 1

Views: 17567

Answers (4)

Nim
Nim

Reputation: 1

Using org.simpleflatmapper.csv :

List<Map<String, Object>> listOfLine = new ArrayList<>(); //Your table
listOfLine.add(new HashMap<>()); //Your line

try (Writer writer = createFile(filename)) {
    CsvWriter<Map> csv = CsvWriter.from(Map.class)
            .separator(';')
            .columns(listOfLine.get(0).keySet().toArray(new String[0]))
            .to(writer);
    
    for (Map<String, Object> line : listOfLine) {
        csv.append(line);
    }
    
    writer.flush();
}

Upvotes: 0

Pranit Maruti Patil
Pranit Maruti Patil

Reputation: 11

Consider the following List

[
{
"header1": "value1",
"header2": "value2",
"header3": "value3",
"header4": "value4"
},
{
"header1": "value1",
"header2": "value2",
"header3": "value3",
"header4": "value4"
},
{
"header1": "value1",
"header2": "value2",
"header3": "value3",
"header4": "value4"
}
]

To covert this into a CSV file here I added a simple method....

public String createCSV(List<LinkedHashMap<String, String>> list) throws IOException{
    List<String> headers = list.stream().flatMap(map -> map.keySet().stream()).distinct().collect(Collectors.toList());

    String path= "dataCSV.csv";

    try(FileWriter writer= new FileWriter(path, true);){
           for (String string : headers) {
                 writer.write(string);
                 writer.write(",");
           }
           writer.write("\r\n");

           for (LinkedHashMap<String, String> lmap : list) {
                 for (Entry<String, String> string2 : lmap.entrySet()) {
                        writer.write(string2.getValue());
                        writer.write(",");
                 }
                 writer.write("\r\n");
           }
    }catch (Exception e) {
        e.printStackTrace();
    }
    return "File created"}

The file will get create and It should contains following entries from List

       header1  header2 header3 header4
        value1  value1  value1  value1
        value2  value2  value2  value2
        value3  value3  value3  value3
        value4  value4  value4  value4

Upvotes: 1

Jose Zevallos
Jose Zevallos

Reputation: 725

the following code solves your problem:

import org.apache.commons.lang.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;

public class SomeMaps {

    public static void main(String[] args) {
        Map<String, String> firstMap = new HashMap<>();
        Map<String, String> secondMap = new HashMap<>();

        firstMap.put("header 1", "value1");
        firstMap.put("header 2", "value2");
        firstMap.put("header 3", "value3");
        firstMap.put("header 4", "value4");

        secondMap.put("header 1", "value5");
        secondMap.put("header 2", "value6");
        secondMap.put("header 3", "value7");
        secondMap.put("header 4", "value8");

        List<Map<String, String>> maps = new ArrayList<>();
        maps.add(firstMap);
        maps.add(secondMap);

        // extract all headers
        SortedSet<String> keys = new TreeSet<>(firstMap.keySet());
        for(Map<String, String> map : maps){
            keys.addAll(map.keySet());
        }


        String header = StringUtils.join(keys, ",");
        System.out.println(header);

        // generate content of CSV file
        for(Map<String, String> map : maps){
            String line = getLineFromMap(map, keys);
            System.out.println(line);
        }
    }

    private static String getLineFromMap(Map<String, String> someMap, SortedSet<String> keys) {
        List<String> values = new ArrayList<>();
        for (String key : keys) {
            values.add(someMap.get(key) == null ? " " : someMap.get(key));
        }
        return StringUtils.join(values, ",");
    }
}

Upvotes: 2

xenteros
xenteros

Reputation: 15852

The following code will help you. It's not ready for your purpose. You'll need to change it, so it prints to a file instead of returning a String.

private static String toCSV(List<Map<String, Object>> list) {
    List<String> headers = list.stream().flatMap(map -> map.keySet().stream()).distinct().collect(toList());
    final StringBuffer sb = new StringBuffer();
    for (int i = 0; i < headers.size(); i++) {
        sb.append(headers.get(i));
        sb.append(i == headers.size()-1 ? "\n" : ",");
    }
    for (Map<String, Object> map : list) {
        for (int i = 0; i < headers.size(); i++) {
            sb.append(map.get(headers.get(i)));
            sb.append(i == headers.size()-1 ? "\n" : ",");
        }
    }
    return sb.toString();
}

For the following input, it gave the following output:

public static void main(String[] args) {
    List<Map<String, Object>> list = new ArrayList<>();
    Map<String, Object> map1 = new HashMap<>();
    map1.put("header1", "value1");
    map1.put("header2", "value2");
    map1.put("header3", "value3");
    map1.put("header4", "value4");
    Map<String, Object> map2 = new HashMap<>();
    map2.put("header1", "value5");
    map2.put("header2", "value6");
    map2.put("header3", "value7");
    map2.put("header4", "value8");
    list.add(map1);
    list.add(map2);
    System.out.println(toCSV(list));
}

enter image description here

Such form is quite reversible, so you can write your own method to read from such CSV to a List<Map<String, String>

Another example, when key is not present in one of the maps:

enter image description here

Upvotes: 9

Related Questions