TIL

[Java] csv 파일 프로그램 여러가지 Tip

빈코 2023. 9. 14. 14:52

오늘은 Java를 이용해서 CSV 파일을 만드는 프로그램을 구성할 때 필요한 여러 가지 tip들을 공유해보려 합니다😁

 

CSV

개요

csv 파일이 무엇인지 잘 아시나요? csv 파일이란 comma-separated variables의 약자로 몇 가지 필드를 쉼표(,)로 구분한 텍스트 데이터 및 텍스트 파일을 뜻합니다. 확장자는 .csv이며 MIME 형식은 text/csv입니다.

 

현업에서는 csv 파일을 많이 다루게 되는데요. 백업 파일을 준비하거나, 기업에서 요청하는 경우도 상당히 많습니다. csv 파일은 단순 텍스트 파일이기 때문에, 개발적인 측면에서 많은 공수가 들어가지 않는다는 장점이 있고, csv 파일을 엑셀로 열었을 때 쉼표(,) 기준으로 셀이 자동으로 나뉘는 편리함도 가지고 있기 때문입니다.

 

그럼 csv 파일을 만들어볼까요?

 

CSV 파일 만들기📙

사실 CSV 파일을 만드는 법은 서두에서 언급했듯이 단순 텍스트 파일을 만드는 거기 때문에 큰 어려움 없이 만들 수 있습니다. 예제 코드를 한번 볼까요?

 

try {
    Path path = Paths.get("파일경로+파일이름"); // ex: /test/test.csv
    if (!Files.notExists(path)) {
        Files.delete(path);
        logger.info("파일이 존재하여 삭제하였습니다.");
    }
    Files.createFile(path);
    logger.info("{} 파일을 생성했습니다."
            , new String[] {pathStr}
    );
} catch(Exception e) {
    logger.error("csv 파일 생성 오류\n", e);
}

해당 코드는 단순히 파일을 생성하는 코드입니다. 기존 파일이 있을 경우에는 해당 파일을 삭제하고 다시 파일을 만드는 방식으로 진행됩니다. if 조건문 하나로 테스트를 진행할 때 파일을 생성했다, 지웠다를 반복하지 않아도 되는 편리함이 있겠죠?

 

그다음은 DB를 연결하고 원하는 리스트를 조회한 후에 파일을 써 내려가면 끝입니다.

 

testCsvDAO testCsvDAO = null;

try {
    testCsvDAO = new testCsvDAO();
} catch (Exception e) {
    logger.error("DB 커낵션 실패\n", e);
    endProgram = true;
} // DB 연결

List<Map<String, Object>> resultListMap = testCsvDAO.getTestList(paramMap); // List 조회

if(!resultListMap.isEmpty()) {
    writeFile(pathStr, resultListMap, separator); // 파일 쓰기
}

csv 파일 만드는 포스팅이기 떄문에 따로 DB 커넥트에 관한 설명은 생략할게요. 저는 testCsvDAO를 만들어서 원하는 정보를 가져오는 getTestList() 함수를 통해 리스트를 가져오고 해당 리스트가 비어 있지 않다면 즉, 리스트를 가져왔다면 writeFile() 함수를 이용해 파일을 써 내려가게 만들었습니다.

 

public static Long writeFile(String pathStr, List<Map<String, Object>> resultListMap, String separator) {
    Path path = Paths.get(pathStr);
    StringBuilder sb = new StringBuilder();

    for (Map<String, Object> resultMapOb : resultListMap) {
        sb.append(resultMapOb.get("제목"));
        sb.append(resultMapOb.get("내용"));
        ...
    }
    
    try {
        Files.write(path, 
        	sb.toString().getBytes(StandardCharsets.UTF_8), 
            StandardOpenOption.APPEND);
    } catch (Exception e) {
        logger.error("파일 쓰기 오류\n오류 데이터\n{}",
                new String[] {sb.toString()}, e);
    }
 }

여기서 매개변수로 받은 pathStr은 아까 만들었던 파일 경로로 생각해주시면 됩니다(파일경로+파일이름)

forEach문을 이용해서 아까전에 리스트를 조회한 resultListMap을 반복해서 돌려주면서 원하는 정보들을 리스트로 쭉 StringBuilder에 append 해주고 마지막에 Files.write() 함수를 이용해서 만들었던 파일에 써 내려가주시면 끝입니다. 간단하죠?

 

여기서 만약 파일에 쓸 내용 중에 한글이 포함되어 있다면 인코딩 방식을 UTF-8로 지정해주면 됩니다. 하지만 Window에서는 이렇게 파일을 생성했을 때, 엑셀로 해당 csv 파일을 열어도 문제가 없지만 Mac에서는 해당 csv 파일을 엑셀로 연다면 한글이 모두 깨지는 현상을 마주하게 됩니다.

 

한글 깨지는 현상

 

CSV 파일 Excel 인코딩 한글 깨짐 현상📘

Excel로 열기

위에 사진처럼 해당 csv 파일을 엑셀로 열었을 때는 인코딩 문제로 모든 한글이 깨지게 됩니다. 이런 방식으로 엑셀을 여는 것이 아니라, 엑셀 자체에서 데이터 가져오기 기능을 사용하셔야 합니다.

 

첫 번째로 엑셀을 여시고 새로운 문서를 생성한 다음에 위에 메뉴바에서 데이터 > 데이터 가져오기 > 텍스트에서 를 클릭해 줍니다.

Excel

 

두 번째로 원하는 파일을 찾아줍니다. 저는 test.csv로 파일을 생성했습니다.

 

csv 파일

 

세 번째로 텍스트 마법사에서 '구분 기호로 분리됨'을 선택해 주시고 원본 파일을 Unicode(UTF-8)로 변경해 줍니다.

 

텍스트 마법사

 

네 번째로 다음을 누르시고 구분 기호를 쉼표로 지정해 줍니다. 이때 구분 기호는 Java 프로그램에서 지정하신 separator입니다. 저는 아까 csv 파일을 만들었을 때 쉼표 기준으로 만들었기 때문에 쉼표로 지정하였습니다. csv 파일은 대부분 쉼표(,) 기준으로 셀을 지정하는데, 사용자에 따라 커스텀 될 수 있기 때문에 이 부분은 독자분이 맞추신 separator 기준으로 지정해 주시면 됩니다.

 

텍스트 마법사

 

마지막으로 셀의 위치를 지정하고 마침 버튼을 누르시면 한글이 깨지지 않고 정상적으로 나오는 것을 확인하실 수 있습니다. 

 

결과

 

CSV 파일 같은 셀 안에서 줄 바꿈 하는 방법📒

java로 엑셀 프로그램을 만들 때 같은 셀 안에서 줄 바꿈을 하는 방법은 흔히 아는 POI 라이브러리를 사용하여 해당 시트를 아래와 같이 설정(cs.setWrapText(true))해주면 끝납니다.

Workbook wb = new XSSFWorkbook();   //or new HSSFWorkbook();
Sheet sheet = wb.createSheet();

CellStyle cs = wb.createCellStyle();
cs.setWrapText(true);

하지만 우리가 만드는 csv 파일은 단순 텍스트 파일이기 때문에, 아래 사진처럼 같은 셀 안에 여러 개의 정보를 표기하고 싶을 때는  따로 지정을 해주어야 합니다. 단순히 개행문자 ("\n") 또는 ("\r")을 삽입하면 같은 셀안에서가 아니라, 아예 따른 줄부터 다시 쓰기 시작합니다.

 

같은 셀 안에서 줄바꿈

 

아까 엑셀 시트를 만들 때는 setWrapText(true)로 지정한 것에 힌트가 있습니다. 해당 부분을 Text로 감싼다는 뜻이기 때문에, csv 파일을 만들 때도 줄 바꿈이 가능하게 하려면 해당 정보를 큰따옴표("")로 감싸주어야 합니다.

 

// 같은 셀안에서 줄바꿈 하고 싶을 경우 ""로 감싼다
sb.append("\"");
sb.append("1번째 줄").append("\n").append("2번째 줄");
sb.append("\"");

 


👨‍👩‍👦‍👦 오픈채팅방 운영

취업을 준비하는 예비 개발자분들을 위한 질문&답변할 수 있는 공간을 만들었습니다. 취업과 이직을 하기 위해서 어떤 걸 중점적으로 준비해야 하는지부터 포트폴리오&이력서 작성법 등 다양한 질문들을 받고 답변을 드립니다. 참여하셔서 다양한 정보 얻고 가시면 좋을 것 같네요😁

 

참여코드 : 456456

https://open.kakao.com/o/gVHZP8dg

 

비전공 개발자 취업 준비방(질문&답변)

#비전공 #개발자 #취업 #멘토링 #부트캠프 #국비지원 #백엔드 #프론트엔드 #중소기업 #중견기업 #자바 #Java #sql

open.kakao.com

 

반응형