Java : poi, jxls를 이용해 Excel 템플릿 양식에 맞춰 다운로드하기.

손유라·2023년 11월 2일
0

템플릿 양식에 맞게 Excel 다운로드 구현하기.

1. 엑셀 다운로드 기능을 구현하기 위해 poi 버전 맞추기

업무를 진행하며, 정해진 엑셀의 양식에 맞게 데이터를 넣어 다운로드 해야 하는 기능을 구현해야 했다. 이리저리 찾아서 이 사람, 저 사람 방식을 따라해 보다 아무리 해도 안 되길래 잠깐 내려놓고 다시 찾아보니! pom.xml에 의존성 주입 시 poi 버전을 맞춰줘야 한다 고 나와있었다.

나는 제일 처음 엑셀 다운로드를 구현할 때 제일 높은 버전의 poi를 사용했다. (최신 버전이 좋은 거겠지... 하면서) 구글링을 통해 아래 버전으로 맞춰 주었다.

<dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.13</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.13</version>
    </dependency>

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>3.13</version>
    </dependency>

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-contrib</artifactId>
        <version>3.7-beta3</version>
    </dependency>

poi-contrib 만 빼고 3.13 버전으로 맞춰주니 엑셀이 다운되었다. (원하는 방식으로는 아니었다...)

2. 이제 템플릿의 형식에 맞게 구현해 보자!

나에게 엑셀 템플릿이 하나 주어졌고, 그 행에 맞는 데이터나 사진이 들어가게 해 달라는 요청이 있었다. 그래서 또 구글링의 힘을 빌려 jxls 라이브러리를 사용한다는 사실을 알았다. 사용법은 아주 간단했다! (템플릿이 셀 병합, 분할, 사진 삽입 등이 많이 들어가 있어서 코드로 템플릿까지 만들어 주기엔 무리가 있다고 판단해 기존 템플릿에 데이터를 입히는 방식을 책했다.)

이런 템플릿에 jxls를 활용하여 데이터를 입혀주었다. el 태그와 상당히 비슷해서 적용하는데에 문제는 없었다. 이제 어떻게 이런 데이터를 줬는지 코드를 살펴보자!

public class MakeJxlsExcel {

    public void download(HttpServletRequest request, HttpServletResponse response, Map<String, Object> model, String fileName)
            throws Exception {

		//resorces 에 저장해 놓은 템플릿의 경로를 만든다.
        
        String tempPath = request.getSession().getServletContext().getRealPath("/resources/templates/temp.xlsx"); //temp파일이 있는 경로
		
        //지정해 줄 파일 명
        fileName = "temFile";

        try {

            FileInputStream is = new FileInputStream(tempPath);
            XLSTransformer xls = new XLSTransformer();

            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Set-Cookie", "fileDownload=true; path=/");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");

            Context context = new Context();
            context.putVar("list", model);

            ByteArrayOutputStream bout = new ByteArrayOutputStream();

            ServletOutputStream os = response.getOutputStream();
			
            //인자로 map을 받았다. map 안에는 템플릿 안에 들어갈 데이터들이 들어있다.
            //ex) map.put("workerList", list);
            Workbook workbook = xls.transformXLS(is, model);

            Sheet sheet = workbook.getSheetAt(0);

            int lastRowNum = sheet.getLastRowNum();

            workbook.write(bout);
            workbook.close();
            bout.close();

            os.write(bout.toByteArray());
            os.flush();
            os.close();


        } catch (IOException e) {
            e.printStackTrace();

        } finally {

        }
    }
}

이렇게 템플릿으로 다운받는 기능이 완성되었다. 완전히 템플릿에 맞게 예쁘게 출력시키는 데에 꼬박 이틀 정도 걸린 것 같다. 주니어 개발자인 나에게 이런 업무가 주어지다니... 겁나고 어려웠다. 하지만! 어렵지만 재미있었다!

profile
유라라랜드에 오신 것을 환영합니다!

1개의 댓글

comment-user-thumbnail
2024년 9월 9일

혹시 jxsl 버전 몇 쓰셨는지 알 수 있을가요?

답글 달기