Search code examples
javalistcsvdictionary

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"); } } 

Solution

  • 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