2

I'm trying to fetch data from excel sheet using Apache poi jars. I have three rows and four columns in my excel. The actual data is in 2nd and 3rd row. 1st row is headers which I'm using as key for fetching the values. While I do this, the output I get always shows the 3rd row data. I have tried debugging it and observed that 2nd row data is getting overridden by 3rd row.

Here is my code snippet

public static void main(String[] args) throws IOException {

    loadExcel();
    
    Map<String, Map<String, String>> superMap = new HashMap<String, Map<String,String>>();
    
    Map<String, String> hm = new HashMap<>();

    for (int i = 1; i < excelSheet.getLastRowNum() + 1; i++) {

        int lastColnum = excelSheet.getRow(0).getLastCellNum();
        for (int j = 0; j < lastColnum; j++) {
            System.out.println("reading excel column");
            String key = excelSheet.getRow(0).getCell(j).getStringCellValue();
            String value = excelSheet.getRow(i).getCell(j).getStringCellValue();
            hm.put(key, value);
        }
        superMap.put("MASTERDATA", hm);
    }

    for (Entry<String, Map<String, String>> set : superMap.entrySet()) {
        System.out.println(set.getKey() + " : " + set.getValue());
    }
}

Output:

MASTERDATA : {Blood Group=test2bg, UserName=test2, Address=test2add, Password=test2pass}

My Data in excel:

Username | Password  | Address | Blood Group
test1    | test1pass |test1add |  test1bg
test2    | test2passs|test2add |  test2bg

I have tried putting the map into a superMap, but still no luck. Any suggestions / advise would help. Thanks in advance.

Kaustubh
  • 506
  • 4
  • 22
  • 3
    The problem is that the `key` is the same for all entries. It works as expected because HashMap can contain just distinct keys. They cannot be duplicated – mslowiak Jul 05 '20 at 11:30
  • Single key can contain only one value. Consider making that value of type which can internally store many values like List. – Pshemo Jul 05 '20 at 11:31
  • Since you're already Apaching... use the org.apache.commons.collections4.MultiValuedMap interface. – Dan M Jul 05 '20 at 11:45

3 Answers3

3

The issue is at this line, where you put the same key for each row

superMap.put("MASTERDATA", hm);

you could use the row number, i.e your i var of the outer loop to make it variable and unique

EDIT

Map<String, Map<String, String>> superMap = new HashMap<String, Map<String,String>>();

for (int i = 1; i < excelSheet.getLastRowNum() + 1; i++) {
    
    Map<String, String> hm = new HashMap<>();

    int lastColnum = excelSheet.getRow(0).getLastCellNum();
    for (int j = 0; j < lastColnum; j++) {
        System.out.println("reading excel column");
        String key = excelSheet.getRow(0).getCell(j).getStringCellValue();
        String value = excelSheet.getRow(i).getCell(j).getStringCellValue();
        hm.put(key, value);
    }
    superMap.put("MASTERDATA_" + i, hm);
}

to get something like

MASTERDATA_1 : {Blood Group=test1bg, UserName=test1, Address=test1add, Password=test1pass}
MASTERDATA_2 : {Blood Group=test2bg, UserName=test2, Address=test2add, Password=test2pass}
Eritrean
  • 15,851
  • 3
  • 22
  • 28
  • Thanks @Eritrean for your answer. I have tried this, but doesn't help. I'm getting the output as - MASTERDATA_1 : {Blood Group=test2bg, UserName=test2, Address=test2add, Password=test2pass} MASTERDATA_2 : {Blood Group=test2bg, UserName=test2, Address=test2add, Password=test2pass} – Kaustubh Jul 05 '20 at 11:50
  • 1
    I overlooked that you initialize your map outside your loop. Move it into the loop. See edit. – Eritrean Jul 05 '20 at 11:57
2

You are putting every row data in the same key in the map. In HashMap single key has one value. So every time it replaces the previous value of MASTERDATA key.

superMap.put("MASTERDATA", hm);

Maybe you need to use List<Map<String, String>> instead of Map<String, Map<String, String>> to store all row data as list. And also need to create map inside in the loop for not using same map reference again.

List<Map<String, String>> list = new ArrayList<>();
for (int i = 1; i < excelSheet.getLastRowNum() + 1; i++) {
    Map<String, String> hm = new HashMap<>();
    int lastColnum = excelSheet.getRow(0).getLastCellNum();
    for (int j = 0; j < lastColnum; j++) {
        System.out.println("reading excel column");
        String key = excelSheet.getRow(0).getCell(j).getStringCellValue();
        String value = excelSheet.getRow(i).getCell(j).getStringCellValue();
        hm.put(key, value);
    }
    list.add(hm);
}
Eklavya
  • 17,618
  • 4
  • 28
  • 57
  • Thanks @Eklavya. I had tried your solution, but still it doesn't work. I'm getting as output - Blood Group test2bg UserName test2 Address test2add Password test2pass Blood Group test2bg UserName test2 Address test2add Password test2pass – Kaustubh Jul 05 '20 at 11:57
  • 1
    @Kaustubh Declare map inside, neither it will use the same map reference.Answer updated – Eklavya Jul 05 '20 at 12:00
0

You can not use the same key twice, because value will be overwritten, but you can put map in your superMap after the loop. In that case you will have "masterdata" key and map with multiple pairs as a value