[Java] 엑셀 파일을 읽고 휴대폰 번호를 기준으로 CSV 파일을 만들어주는 프로그램

Denia·2022년 7월 10일
0

이게 어쩌다보니 해당 게시글들이 시리즈가 되어가고 있습니다.

이번에도 쇼핑몰 운영 일을 돕다가 불편한 부분이 있었고 코딩을 배웠으니 "프로그램적으로 해결하자" 라고 생각해서 프로그램을 만들어봤습니다.

불편한 부분

주문이 들어온 것을 배송하기 위해서 주문 목록을 엑셀 파일로 다운로드 받고 (엑셀 파일로 제공하는건 쇼핑몰에서 지원) 해당 파일을 인쇄해서 직접 보면서 하나 하나 물건들을 포장하고 있습니다.

다운로드 받은 엑셀 파일을 확인해보면 고객 명단 사이에 행이 한칸이라도 떨어져있거나 서로 다른 고객이면 서로 배경색이 다르거나 그런거 하나 없이 모두 다 다닥다닥 붙어있다 보니까 인쇄한 파일을 보면서 포장하는게 너무 힘들다는 지인의 불만

※ 힘든 점

  1. 고객 중에는 동명이인 들도 존재 (휴대폰 번호를 기준으로 고객을 나눌 예정)
  2. 글자를 크게하면 종이를 많이 사용
  3. 글자를 작게하면 종이는 아끼지만 알아보기가 너무 힘듬

요청사항 : 서로 다른 고객이면 해당 고객들 사이에 한칸씩 빈 행을 넣어주면 좋겠다 (이렇게 되면 엑셀에서 빈 행만 잡아서 색을 넣어주면 더욱 더 알아보기가 쉬움)

프로그램 동작시에 필요한 파일

주문자의 구입한 상품 과 주문자의 휴대폰 번호 가 담겨있는 엑셀 파일. (사용하고 있는 쇼핑몰 사이트에서 다운로드 받음.)

프로그램 동작 구성

  1. 프로그램을 실행하면 엑셀 파일을 쭉 읽으면서 휴대폰 번호를 기준으로 같은 사람이면 쭉 붙여서 CSV 파일로 저장
  2. 휴대폰 번호가 다른 사람이면 그 사람과 다른 사람 사이에 한칸의 빈 행을 넣어서 CSV 파일로 쭉 저장
  3. CSV 파일로 저장이 완료되면 엑셀로 해당 파일을 열어서 인쇄한다.

프로그램 사용법

  1. IDE에서 해당 코드를 JAR 파일로 만듬
  2. Launch4J 프로그램을 사용하여 JAR 파일을 exe 파일로 변환
  3. 지인 컴퓨터에서 exe 파일을 다운로드 하여 사용
    (※Launch4J를 사용할때 설정을 좀 만져주면 exe 파일로 실행 시켰을때 JRE가 없으면 자동으로 JRE를 다운로드 받을 수 있게 사이트가 열린다.)

사용한 코드 (주석을 달아놓음)

특징
1. 프로그램 종료 전에 스캐너의 nextLine 메서드를 추가해서 에러 발생시에 바로 꺼지지 않고 메세지를 확인 후 꺼지게 만듬
2. Gradle을 사용해서 Build 후 jar 파일로 만듬 -> 다른 컴퓨터에서 사용하기 위해서
3. OpenCSV , apache.poi 라이브러리를 사용함

더 자세한 내용은 아래의 Github 을 참고해주세요.

Github
https://github.com/Denia-park/SplitUserInExcel.git

Main

    public static void main(String[] args) {
        System.out.println("유저 나누기 프로그램을 시작합니다. [ " + PROGRAM_VERSION + " ]");

        Scanner sc = new Scanner(System.in); // 사용자로부터 데이터를 받기 위한 Scanner

        String path = System.getProperty("user.dir") + "\\"; //현재 작업 경로
        String fileName = "clothesOptionList.xlsx"; //파일명 설정

        XSSFSheet sheetDataFromExcel = readExcel(path, fileName); //엑셀 파일 Read
        if (sheetDataFromExcel == null) { //파일을 못 읽어오면 종료.
            System.out.println("파일을 찾지 못했으므로 프로그램을 종료 합니다.");

            System.out.println("Enter 를 치면 정상 종료됩니다.");
            sc.nextLine(); //프로그램 종료 전 Holding
            return; //프로그램 종료
        }

        //행 갯수 가져오기
        int rows = sheetDataFromExcel.getPhysicalNumberOfRows();

        XSSFRow row = sheetDataFromExcel.getRow(0); //Title Row 가져오기
        int cells = row.getPhysicalNumberOfCells(); //Title Cell 수 가져오기
        String[][] dataBufferArr = new String[2][cells]; //행을 읽어서 저장해둘 배열을 생성
        int currentSaveOrder = 0; //dataBufferArr 에서 몇번째 배열인지 알려줄 인자
        NumberFormat f = NumberFormat.getInstance(); //엑셀에서 NumberFormat이 나왔을때 저장할 수 있게 생성함
        f.setGroupingUsed(false);	//지수로 안나오게 설정

        //반드시 "행(row)"을 읽고 "열(cell)"을 읽어야함 ..
        //rowIndex = 0 => Title
        for(int rowIndex = 1 ; rowIndex < rows ; rowIndex++) {
            row = sheetDataFromExcel.getRow(rowIndex);

            for (int i = 0; i < cells; i++) {
                XSSFCell cell = row.getCell(i);
                dataBufferArr[currentSaveOrder][i] = readCell(cell,f);
            }

            //첫번째 행은 비교할게 없으므로 넘어간다.
            if(rowIndex == 1){
                if(dataBufferArr[currentSaveOrder][RECEIVER_PHONE_NUMBER_CELL_INDEX] == null){
                    throw new RuntimeException("휴대폰 번호 가 Null 입니다. ");
                }
            }
            //첫번째 행을 제외한 모든 행을 CSV로 저장
            else{
                writeDataToCSV(path, dataBufferArr, currentSaveOrder);
            }

            currentSaveOrder ^= 1; //dataBufferArr 에 저장할 순서 변경 0 -> 1 , 1 -> 0 : XOR을 사용했다.
        }

        //마지막 행 이므로 다시 한번 저장을 해줘야함.  그대로 csv에 저장하기.
        writeDataToCSV(path, dataBufferArr, currentSaveOrder);

        System.out.println("작업이 완료되었습니다.");

        System.out.println("Enter 를 치면 정상 종료됩니다.");
        sc.nextLine(); //프로그램 종료 전 Holding
    }

Build.gradle

//JAR 파일을 만들기 위해서 필요한 부분
jar {
    manifest {
        attributes 'Main-Class': 'org.example.Main'
    }
    // 이 부분 추가
    from {
        configurations.runtimeClasspath.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    // 이 부분 추가
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

//의존성
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'

    // https://mvnrepository.com/artifact/com.opencsv/opencsv
    implementation 'com.opencsv:opencsv:5.6'

    // https://mvnrepository.com/artifact/org.apache.poi/poi
    implementation 'org.apache.poi:poi:5.2.2'

    // https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml
    implementation 'org.apache.poi:poi-ooxml:5.2.2'
}
profile
HW -> FW -> Web

0개의 댓글