My approach is to read column names and store them in the list for later use during the read of rows with actual data. After data from the row being parsed result is stored into map with code as key and list of pairs: cell value and cell header name.
private static void readExcel(XSSFSheet sheet) { Map<Long, List<Column>> data = new HashMap<>(); List<String> columnNames = new ArrayList<>(); boolean isTableHeaderFound = false; for (int i = 0; i <= sheet.getLastRowNum(); i++) { XSSFRow currentRow = sheet.getRow(i); if (skipRow(currentRow)) continue; if (!isTableHeaderFound) { setTableHeader(currentRow, columnNames); isTableHeaderFound = true; continue; } readRowValues(data, currentRow, columnNames); } printData(data); }
Read row method:
private static void readRowValues(Map<Long, List<Column>> data, XSSFRow currentRow, List<String> columnNames) { Long code = -1L; List<Column> rowValues = new ArrayList<>(); for (short cellIdx = currentRow.getFirstCellNum(); cellIdx < currentRow.getLastCellNum(); cellIdx++) { if (cellIdx == currentRow.getFirstCellNum()) { code = Long.valueOf((int)currentRow.getCell(cellIdx).getNumericCellValue()); } else { rowValues.add(new Column(columnNames.get(cellIdx), Double.valueOf(currentRow.getCell(cellIdx).getNumericCellValue()))); } } data.put(code, rowValues); }
Read cell column names:
private static void setTableHeader(XSSFRow currentRow, List<String> columnNames) { for (short cellIdx = currentRow.getFirstCellNum(); cellIdx < currentRow.getLastCellNum(); cellIdx++) columnNames.add(currentRow.getCell(cellIdx).getStringCellValue()); }
Helper method which determines wheter row should be skipped:
private static boolean skipRow(XSSFRow currentRow) { if(currentRow == null) return true; if (currentRow.getLastCellNum() == currentRow.getFirstCellNum()) return true; for (short cellIdx = currentRow.getFirstCellNum(); cellIdx < currentRow.getLastCellNum(); cellIdx++) if (currentRow.getCell(cellIdx) != null) return false; return true; }
Finally printing result:
private static void printData(Map<Long, List<Column>> data) { for (Map.Entry<Long, List<Column>> entry : data.entrySet()) { for (Column column : entry.getValue()) { System.out.println(entry.getKey() + "," + column.getColumnName() + "," + column.getValue()); } } }