??? : 님아 살려주센 ㅠㅠ
SHH : 롸?
??? : 엑셀 데이터 정리하는데 오전이 날라감 이거 쉽게 하는 방법없을까?
SHH : 뭐하는건데??
사실 이전에도 Help를 쳐서 도와준적이 있었는데 맘에 들었나봐.
샘플로 받은 엑셀 데이터를 보니
일자별로 사람들의 마지막 시간만 필요했던것!
apache.poi
를 사용해 데이터를 읽었다 5.2.2 버전
절대 경로로 하면 세팅해 주기 귀찮으니 상대경로로 데이터를 읽도록 했다.
File readFilePath = new File("./INPUT.xlsx");
Workbook workbook = new XSSFWorkbook(new FileInputStream(readFilePath));
이후 Row, Cell
데이터 읽는 부분은 구글링
dto
를 사용하다 보니 값 세팅에 고민
엑셀 열 순서가 변함이 없다길래 열에 대한 순서 정보를 dto
에 넣었다.
int cellIndex = readCell.getColumnIndex();
excelHeaderData.setHeaderIndexValue(cellIndex, cellData);
public void setHeaderIndexValue(int index, String value){
if(index == 0){
this.issueDate = LocalDate.parse(value, DeleteDuplicateExit.dateFormatter);
} else if(index == 1){
this.issueTime = LocalTime.parse(value, DeleteDuplicateExit.timeFormatter);
} else if(index == 2){
this.cardNumber = value;
} else if(index == 3){
this.userName = value;
} else if(index == 4){
this.companyName = value;
} else if(index == 5){
this.deviceName = value;
}
}
위 순서로 데이터 정리를 하기로 생각했었다.
List<List<ExcelHeader>> groupingDate = excelHeaderDataList.stream()
.collect(Collectors.groupingBy(ExcelHeader::getIssueDate, Collectors.groupingBy(ExcelHeader::getCardNumber)))
.entrySet()
.stream()
.sorted((a, b) -> a.getKey().compareTo(b.getKey()))
.map(x -> x.getValue()
.entrySet()
.stream()
.map(z -> z.getValue())
.map(y -> y.stream()
.reduce((a, b) -> (a.getIssueTime().isAfter(b.getIssueTime())) ? a : b)
.get())
.sorted((a, b) -> a.getIssueTime().compareTo(b.getIssueTime()))
.collect(Collectors.toList()))
.collect(Collectors.toList());
collect
를 통해 1번, 2번을 한번에 처리Collectors.groupingBy 넘나 좋은것
sorted
로 일자순 정렬
map
으로 일자 안 카드번호 접근
reduce
를 통해 시간값을 비교하여 최대 값 선택
sorted
로 시간순 정렬
Cell cell0 = row.createCell(0);
Cell cell1 = row.createCell(1);
Cell cell2 = row.createCell(2);
Cell cell3 = row.createCell(3);
Cell cell4 = row.createCell(4);
Cell cell5 = row.createCell(5);
cell0.setCellValue(data.getFormatIssueDate());
cell1.setCellValue(data.getFormatIssueTime());
cell2.setCellValue(data.getCardNumber());
cell3.setCellValue(data.getUserName());
cell4.setCellValue(data.getCompanyName());
cell5.setCellValue(data.getDeviceName());
처음엔 위와 같이 했지만, 맘이 불편해
dto
의 필드 정보를 가져와 foreach
를 돌리기로 한다
Class dataClass = ExcelHeader.class;
Field[] fields = dataClass.getDeclaredFields();
int cellIndex = 0;
for (Field field : fields) {
field.setAccessible(true); //private 필드로 인해 접근 가능하도록 해제
Object object = field.get(data);
Cell cell = row.createCell(cellIndex++);
cell.setCellValue(object.toString());
}
열 추가에 따른 수정범위는 줄었지만 속도엔 손해를 본느낌
시간이 없어서 요정도로 만들고 jar로 묶어서 전달
몇 시간이 걸리던 작업이 몇 초 만에 끝나게 되었다
소스는 git에서 확인해주시면 되겠습니다.