简体   繁体   中英

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

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

在此处输入图片说明

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:

在此处输入图片说明

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM