살려줘 시리즈 1

S_H_H·2022년 9월 16일
0

집사 도움!

목록 보기
1/3
??? : 님아 살려주센 ㅠㅠ
SHH : 롸?
??? : 엑셀 데이터 정리하는데 오전이 날라감 이거 쉽게 하는 방법없을까?
SHH : 뭐하는건데??

사실 이전에도 Help를 쳐서 도와준적이 있었는데 맘에 들었나봐.

img

샘플로 받은 엑셀 데이터를 보니
일자별로 사람들의 마지막 시간만 필요했던것!


1. 엑셀 데이터 읽기

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

2. 데이터 정리

  1. 일자 기준으로 그룹핑
  2. 카드 번호로 그룹핑 (이름은 중복일 수 있다해서)
  3. 마지막 시간만 남기기

위 순서로 데이터 정리를 하기로 생각했었다.

        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로 시간순 정렬

3. 엑셀 제작

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에서 확인해주시면 되겠습니다.

profile
LEVEL UP

0개의 댓글