hanker

Spring - excel to csv 파일 변환 (한글 깨짐 문제 완벽 해결) 본문

SPRING

Spring - excel to csv 파일 변환 (한글 깨짐 문제 완벽 해결)

hanker 2024. 10. 6. 14:56

Excel 파일을 csv파일로 변환하는 방법은 여러가지가 있다.

Excel 자체에서 다른 이름으로 저장 누르고 CSV 파일로 저장하면 저장되지만, 우리는 코드에서 자동으로 변환시켜줘야 한다.

이 외에도 여러가지 방법중에 JAVA 코드로 변환하는 방법을 알아보자

 

public String excelToCsv() {
    String excelFilePath = "/data/2021.xlsx";  // 변환할 Excel 파일 경로
    String csvFilePath = "/data/2021.csv";    // 결과로 저장할 CSV 파일 경로

    return convertXlsxToCsv(excelFilePath, csvFilePath);
}

2021.xlsx 파일이 있는곳을 적어주고, csv로 저장될 경로를 지정해준다.

 

convertXlsxToCsv 메서드를 살펴보자

public String convertXlsxToCsv(String excelFilePath, String csvFilePath) {
    try (FileOutputStream fos = new FileOutputStream(csvFilePath);
         OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
         BufferedWriter writer = new BufferedWriter(osw)) {

        // UTF-8 BOM 추가
        fos.write(new byte[] {(byte)0xEF, (byte)0xBB, (byte)0xBF});

        // 엑셀 파일 열기
        FileInputStream fis = new FileInputStream(excelFilePath);
        XSSFWorkbook workbook = new XSSFWorkbook(fis);

        // 첫 번째 시트만 변환 (필요시 다른 시트를 반복해서 처리할 수 있음)
        XSSFSheet sheet = workbook.getSheetAt(0);
        Iterator<Row> rowIterator = sheet.iterator();

        while (rowIterator.hasNext()) {
            Row row = rowIterator.next();
            Iterator<Cell> cellIterator = row.iterator();

            StringBuilder rowContent = new StringBuilder();
            while (cellIterator.hasNext()) {
                Cell cell = cellIterator.next();
                String cellValue = getCellValueAsString(cell);

                // CSV 포맷에 맞게 큰따옴표로 감싸기 (필드 내에 쉼표가 있을 수 있기 때문)
                rowContent.append("\"").append(cellValue.replace("\"", "\"\"")).append("\"").append(",");
            }

            // CSV 포맷에 맞게 마지막 쉼표 제거 후 줄바꿈 추가
            if (rowContent.length() > 0) {
                rowContent.setLength(rowContent.length() - 1); // 마지막 쉼표 제거
            }
            writer.write(rowContent.toString());
            writer.newLine();
        }

        return "Excel to CSV 전환성공.";

    } catch (IOException e) {
        return "Excel to CSV 전환실패: " + e.getMessage();
    }
}

코드를 보면 이해 안가는 부분은 따로 없을거라 생각이 드는데, 한글 처리를 해야하는 경우

fos.write(new byte[] {(byte)0xEF, (byte)0xBB, (byte)0xBF});

한글이 깨지므로 중간에 이 코드를 꼭 추가해야한다. 

 

코드 흐름으로는 FileInputStream으로 데이터를 읽어서 메모리로 가져온 다음, 데이터변환, FileOutputStream을 통해서 CSV파일로 저장하는 코드 흐름이다.

 

getCellValueAsString 메서드에 대해서 알아보자.

private static String getCellValueAsString(Cell cell) {
    switch (cell.getCellType()) {
        case Cell.CELL_TYPE_STRING:
            return cell.getStringCellValue();
        case Cell.CELL_TYPE_NUMERIC:
            if (DateUtil.isCellDateFormatted(cell)) {
                return cell.getDateCellValue().toString(); 
            } else {
                return Double.toString(cell.getNumericCellValue());
            }
        case Cell.CELL_TYPE_BOOLEAN:
            return Boolean.toString(cell.getBooleanCellValue());
        case Cell.CELL_TYPE_FORMULA:
            FormulaEvaluator evaluator = cell.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
            return getCellValueAsString(evaluator.evaluateInCell(cell));
        case Cell.CELL_TYPE_BLANK:
            return "";
        default:
            return "";
    }
}

POI  최신버전을 쓰면 Enum 형태로 사용이 가능하다. 근데 나는 3.15버전을 사용해서 Cell.CELL_TYPE을 붙혀줬다.

위 메서드는 EXCEL셀 값을 읽어서 문자열로 변환해주는 기능을 한다.

문자열, 숫자, 날짜, 불리언, 수식, 빈값, 기타 처리를 해준다.다른 유형이 있다면 추가해서 사용하면 된다.

 

 

실행 시켜보면 잘 변경된 것이 확인된다.

 

 

 

 

끝.