TIL

Java 엑셀 만드는 방법 완벽정리(JS에서 Controller까지)

빈코 2024. 1. 15. 15:06

 

 

Java Excel

개요

안녕하세요. 빈코입니다! 오늘은 프로젝트에서 자주 사용하는 기능인 엑셀 출력 기능에 대해 알아보려고 합니다. 엑셀 라이브러리인 POI 적용부터 엑셀을 만드는 방법, 엑셀 내용을 커스텀하는 방법 등 다양하게 소개해드리고자 합니다. 이번 포스팅은 js에서 엑셀 만들기까지 간단한 예시와 함께 작성했습니다. 혹여 엑셀 관련 함수들만 보실 분들은 포스팅 맨 하단에 위치해 있습니다😊

 

엑셀 라이브러리 POI📙

POI 라이브러리를 사용하면 엑셀(.xls, .xlsx), 파워포인트(. ppt,. pptx), 워드(. doc,. docx) 등의 Microsoft Office 파일 형식을 다룰 수 있습니다. 프로젝트에 POI 라이브러리를 적용하는 방법은 apache 다운로드 홈페이지(https://poi.apache.org/download.html)에 들어가서 최신 버전이나 원하는 버전으로 POI 라이브러리를 설치해 주시고, File -> Project Structure -> Libraries(인텔리제이 경로 예시)에 설치했던 파일들을 추가시켜 주면 끝이 납니다.

 

apache POI

 

라이브러리 추가

첫 시작은 JS📘

대부분의 프로젝트 상 화면에서 사용자가 엑셀 관련 버튼을 클릭해야 엑셀 출력 기능이 실행이 됩니다. 클릭 이벤트를 clickExcelExport()라고 가정했을 때 js에서 Controller로 어떻게 넘기는지 또 원하는 특정 값을 같이 넘기는 방법에 대해 알아보려고 합니다.

 

여기서 원하는 특정 값은 사용자가 검색한 내용만 엑셀로 다운로드할 경우, 검색 필드와 검색어를 Controller에 같이 넘겨줘야 하는 경우도 있습니다. 그래야만 Controller에서 DB의 내용을 찾을 때 넘겨받은 검색어로 조회가 가능하기 때문입니다. 코드를 한번 살펴볼까요?

 

function clickExcelExport() {
    var params = {"category":"Blog"}; //해당 값은 extend 예시 위한 세팅
    
    var search_field = $('#search_field').val(); //검색 타입(ex: 제목/내용/작가 중 선택 값)
    var search_value = $('#search_value').val(); //검색어(ex:Binco)
    
    try {
    	$.extend(params, {"search_field":search_field, "search_value":search_value})
    } catch(error) {
    	console.log(error);
    }
    
    formSubmit("binco/test/excel/export", params);
}

 

사용자가 엑셀 버튼을 클릭해서 clickExcelExport() 함수가 실행되면, 첫 번째로 params라는 변수에 Controller에서 필요한 값을 세팅을 해줍니다. 포스팅상에서는 category라는 값을 넣었지만, 독자분들은 해당 프로젝트에서 필요한 값들을 세팅하시면 됩니다! (없으시면 생략하셔도 됩니다)

 

이후에 사용자가 선택한 검색 타입과 검색어를 각각 search_field, search_value에 세팅을 해줍니다. 그리고 $.extend 함수를 사용해서 category 값과 검색 관련 값들을 병합하여 줍니다. 

 

이후에 formSubmit 함수를 활용해서 Controller에 등록한 URL과 세팅한 params를 넣어주면 js단에서는 끝이 납니다😃

 

Controller📒

Controller에서 할 작업은 js에서 받아 온 검색어를 이용해서 Database의 내용을 조회하고, 조회한 데이터를 이용하여 엑셀을 만들어야 합니다. 포스팅의 주 내용은 엑셀 만드는 작업이기 때문에, 데이터를 조회하는 방법은 생략했습니다. 코드가 길어서 해당 코드들을 주석으로 설명했습니다. 결과 예시는 코드 다음에 바로 나옵니다 :)

 

@PostMapping(value = "binco/test/excel/export")
@ResponseBody
public void excelExport(HttpServletResponse response, @RequestParam Map<String, String> paramMap, HttpSession session, HttpServletRequest request) throws IOException {
   List<Map<String,Object>> results = bincoMapper.getExcelData(paramMap); // 데이터 조회
   
   /**
    * 데이터 예시
    results = [
    	{"title":"Binco Blog", "content":"블로그"},
        {"title":"Binco Youtube", "content":"유튜브"}
    ]
    */
    
   XSSFWorkbook workbook = null;
   ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
   
   /** 
    * Excel Style
    */
    XSSFCellStyle styleSheetTitle = workbook.createCellStyle();
    Font titleFont = workbook.createFont();
    titleFont.setFontHeightInPoints((short)18);
    styleSheetTitle.setFont(titleFont);
    styleSheetTitle.setAlignment(HorizontalAlignment.CENTER);
    
    XSSFCellStyle styleRowTitle = workbook.createCellStyle();
    Font rowFont = workbook.createFont();
    rowFont.setFontHeightInPoints((short)9);
    styleRowTitle.setFont(rowFont);
    styleRowTitle.setAlignment(HorizontalAlignment.CENTER);
    styleRowTitle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
    styleRowTitle.setVerticalAlignment(VerticalAlignment.CENTER );
    styleRowTitle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
    
   
   try{
     workbook = new XSSFWorkBook(); //엑셀 생성
     XSSFSheet sheet = workbook.createSheet("Binco Excel") //엑셀 시트 생성
     
     workbook.getSheetAt(0).setColumnWidth(0, 1500);
     workbook.getSheetAt(0).setColumnWidth(1, 3000);
     workbook.getSheetAt(0).setColumnWidth(2, 5000); // 엑셀 넓이 조정
     
     int row = 0; 
     XSSFRow sheetTitle = sheet.createRow(row); // 0번째 로우 생성
     sheetTitle.createCell(0).setCellValue("Binco Excel"); // 0번째 제목 추가
     sheetTitle.getCell(0).setCellStyle(styleSheetTitle); // 0번째 셀에 제목 스타일 추가
     sheet.addMergedRegion(new CellRangeAddress(0,0,0,results.size())); // 제목 합치기
     
     sheet.createRow(++row); // 로우 한개 더 생성
     
     XSSFRow rowTitle = sheet.createRow(++row) // 데이터 제목 로우 생성
     
     rowTitle.createCell(0).setCellValue("순번");
     rowTitle.getCell(0).setCellStyle(styleRowTitle); // 테이블 제목 스타일 입히기
     
     rowTitle.createCell(1).setCellValue("제목");
     rowTitle.getCell(1).setCellStyle(styleRowTitle); // 테이블 제목 스타일 입히기
     
     rowTitle.createCell(2).setCellValue("내용");
     rowTitle.getCell(2).setCellStyle(styleRowTitle); // 테이블 제목 스타일 입히기
     
     for(int i=0; i<results.size(); ++i){
       Map<String, Object> map = results.get(i);
       XSSFRow rowData = sheet.createRow(++row); // 로우 생성
       rowData.createCell(0).setCellValue(i);
       rowData.createCell(1).setCellValue(map.get("title"));
       rowData.createCell(2).setCellValue(map.get("content"));
     } // 데이터 삽입
     
     workbook.write(outByteStream);
     
   }catch(Exception e){
     logger.error(e.toString(),e);
   }finally{
     if(outByteStream != null) {
       try{
         outByteStream.close();
       }catch(IOException e) {
         logger.error(e.toString(), e);
       }
     }
     if(workbook != null) {
       try {
         workbook.close();
       }catch(IOException e) {
         logger.error(e.toString(), e);
       }
     }
   }
   
    byte[] outArray = outByteStream.toByteArray();
    String fileName = "binco.xlsx";
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setHeader("Content-Disposition", "attachment; filename="+ fileName);
    response.setContentLength(outArray.length);

    ServletOutputStream out = response.getOutputStream();
    out.write(outArray);
    out.flush();
    out.close();
}

 

엑셀 결과

 

 

엑셀 다양한 함수 정리📗

위에서 나온 함수들도 있지만, 대부분 자주 사용하는 함수들을 위주로 알려드리려고 합니다! 더 많은 함수들은 Apache POI 문서를 참고하시면 됩니다😃

 

명령어 내용 예시
createSheet() 시트를 생성합니다 Sheet sheet = workbook.createSheet("첫번째 시트");
createRow() 행을 생성합니다 Row row = sheet.createRow(0);
createCell() 셀을 생성합니다 Cell cell = row.createCell(0);
setCellValue() 셀에 값을 설정합니다 cell.setCellValue("Binco Blog!!");
addMergedRegion() 셀을 병합합니다 sheet.addMergedRegion(new CellRangeAddress(0,0,0,2)); A1,B1 병합
setCellStyle() 셀에 스타일을 설정합니다 CellStyle binco = workbook.createCellStyle();
cell.setCellStyle(binco);
setCellFormula() 셀에 수식을 설정합니다 cell.setCellFormula("SUM(A1:A2)");
setBold() 텍스트를 굵게 설정합니다 createFont()로 Bfont 생성 후 setBold(true) -> setCellStyle(Bfont);
setHorizontalAlignment() 수평 정렬을 설정합니다 CellStyle binco = workbook.createCellStyle();
binco.setAlignment(HorizontalAlignment.CENTER);
cell.setCellStyle(binco);
setVerticalAlignment() 수직 정렬을 설정합니다 CellStyle binco = workbook.createCellStyle();
binco.setVerticalAlignment(VerticalAlignment.CENTER);
cell.setCellStyle(binco);

 

 

마치며

지금까지 apache POI를 활용해서 엑셀 만드는 방법에 대해 알아보았습니다. 처음 해보시는 분들이라면 생각보다 코드가 길어서 어려우실 수 있을 텐데, 코드 한줄한줄 따라가다 보면 엑셀에서 필요로 하는 것들이 눈에 보일 겁니다! 각자 상황에 맞게 엑셀 커스텀 작업 잘 만들어가시길 바랍니다🙇‍♂️

 


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

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

 

참여코드 : 456456

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

 

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

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

open.kakao.com

 


👨‍💻 전자책 출간

아울러 제가  🌟비전공자에서 2년 만에 보안 전문 중견기업으로 이직 한 방법들을 정리한 전자책을 출간하게 되었습니다. 어떤 걸 공부해야 하는지, 이직을 위해서 무엇을 준비해야 하는지, 제가 받았던 기술 면접 리스트 등 다양한 목차로 구성되어 있습니다. 또한, 구매 시 1:1 채팅을 이용하여 포트폴리오 첨삭을 도와드리고 있습니다. 🐕전자책으로 얻은 모든 수익은 유기견 센터 '팅*벨 입양센터'에 후원될 예정입니다. 관심 있으신 분들은 아래 링크를 참고해 주세요😁

https://kmong.com/gig/480954

 

비전공개발자 2년만에 중견기업 들어간 방법 | 14000원부터 시작 가능한 총 평점 0점의 전자책, 취

0개 총 작업 개수 완료한 총 평점 0점인 Binco의 전자책, 취업·이직 전자책 서비스를 0개의 리뷰와 함께 확인해 보세요. 전자책, 취업·이직 전자책 제공 등 14000원부터 시작 가능한 서비스

kmong.com


 

반응형