일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 네트워크
- ChatGPT
- java
- jsp
- SQL
- 백준
- 개발자
- HTTP
- 파이썬
- Python
- 프로그래머스
- 서버
- 정렬알고리즘
- 개발
- 챗지피티
- Spring
- 그리디알고리즘
- 알고리즘코딩테스트
- JQuery
- codingtest
- javascript
- HTTP상태
- 하루코딩
- 자바
- 알고리즘
- 코딩테스트
- 탐욕알고리즘
- SQLD
- SQLP
- API
- Today
- Total
개발자's Life
[JAVA] POI 라이브러리를 이용한 Excel Down 기능 구현 본문
회사에서 엑셀 업로드 및 다운로드 기능을 구현하며 개발을 이어 나가고 있습니다.
오늘은 엑셀 다운로드의 기본 구성에 대해 쉽게 설명 드릴 예정입니다
개발 환경
- Java 17
- 인텔리제이
- Gradle
1. Gradle 의존성 추가
// POI 라이브러리 추가.(xls)
implementation 'org.apache.poi:poi-ooxml:4.1.2'
2. 화면구성(필요할 경우만 참고)
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-aFq/bzH65dt+w6FI2ooMVUpc+21e0SRygnTpmBvdBgSdnuTN7QbdgL+OapgHtvPp" crossorigin="anonymous">
<title>Excel 예제</title>
</head>
<body>
<form action="/excelDown" method="POST">
<div>
<label>엑셀 파일명</label>
<input type="text" name="fileName">
</div>
<div>
<label>엑셀 열 갯수</label>
<input type="number" name="colNum">
</div>
<div>
<label>엑셀 행 갯수</label>
<input type="number" name="rowNum">
</div>
<button class="btn btn-primary rounded-pill px-3" type="submit">엑셀 다운</button>
</form>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha2/dist/js/bootstrap.bundle.min.js" integrity="sha384-qKXV1j0HvMUeCBQ+QVp7JcfGl760yU08IQ+GpUo5hlbpg51QRiuqHAJz8+BrxE/N" crossorigin="anonymous"></script>
POST 타입으로 Mapping 시도.
3. Controller 단에서 Mapping
package excel.excelproject.controller;
import excel.excelproject.model.FormModel;
import excel.excelproject.service.MainServiceImpl;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;
@Controller
public class MainController {
@Autowired
MainServiceImpl mainService;
@GetMapping("/")
public String mainPage(){
return "index.html";
}
@PostMapping("/excelDown")
public @ResponseBody Map<Object, Object> excelDown(HttpServletRequest request, HttpServletResponse response, FormModel formModel){
HashMap<Object, Object> map = new HashMap<>();
String result = mainService.excelDown(request, response, formModel);
map.put("result", result);
return map;
};
}
필요에 따라 Map 타입 활용하시면 될 거 같습니다.
4. Sevice 단에서 Excel 기능 구현
package excel.excelproject.service;
import excel.excelproject.model.FormModel;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.net.URLEncoder;
@Service
public class MainServiceImpl implements MainService{
@Override
public String excelDown(HttpServletRequest request, HttpServletResponse response, FormModel formModel) {
try {
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet();
// 파일명 설정
String tempName = formModel.getFileName() + ".xls";
int rowNum = formModel.getRowNum();
int colNum = formModel.getColNum();
String name = "출력될파명이름";
// 한글이 포함
if(tempName.matches(".*[ㄱ-ㅎㅏ-ㅣ가-힣]+.*")) {
// 브라우저 별 한글 인코딩 https://byul91oh.tistory.com/487 참고
String header = request.getHeader("User-Agent");
if (header.contains("Edge")){
name = URLEncoder.encode(tempName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment;filename=\"" + name + "\".xlsx;");
} else if (header.contains("MSIE") || header.contains("Trident")) { // IE 11버전부터 Trident로 변경되었기때문에 추가해준다.
name = URLEncoder.encode(tempName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment;filename=" + name + ".xlsx;");
} else if (header.contains("Chrome")) {
name = new String(tempName.getBytes("UTF-8"), "ISO-8859-1");
response.setHeader("Content-Disposition", "attachment; filename=\"" + name + "\".xlsx");
} else if (header.contains("Opera")) {
name = new String(tempName.getBytes("UTF-8"), "ISO-8859-1");
response.setHeader("Content-Disposition", "attachment; filename=\"" + name + "\".xlsx");
} else if (header.contains("Firefox")) {
name = new String(tempName.getBytes("UTF-8"), "ISO-8859-1");
response.setHeader("Content-Disposition", "attachment; filename=" + name + ".xlsx");
}
} else {// 한글 미 포함
name = tempName;
}
// 입력 Row 만큼 반복문 실행
for (int rowCnt = 0; rowCnt < rowNum; rowCnt++){
Row row = sheet.createRow(rowCnt);
// 입력 Column 만큼 반복문 실행
for(int colCnt = 0; colCnt < colNum; colCnt++){
row.createCell(colCnt).setCellValue("cell Number : " + colCnt);
}
}
// 엑셀 셋팅
response.setContentType("ms-vnd/excel");
// name 이 엑셀 파일명
response.setHeader("Content-Disposition", "attachment;filename=" + name);
workbook.write(response.getOutputStream());
workbook.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
return null;
}
}
저는 Param 으로 파일명, Row 갯수, Column 갯수 를 받아 출력하였습니다.
파일명이 한글이 포함되면 인코딩 에러가 발생하여
https://byul91oh.tistory.com/487
[JAVA]브라우저별 한글 파일명 인코딩 _ excel파일
서버에서 프론트로 파일을 전송할 때 한글로 파일명을 보내면 깨지는 경우가 다반사입니다. 따라서 아래 로직과 같이 User-Agent header 값을 가져와서 브라우저 별로 인코딩을 해 줘야 한글이 깨지
byul91oh.tistory.com
코드 활용하여 한글일 경우에도 정상적으로 다운로드 가능하게 구현하였습니다.
주석으로 자세히 달아서 참고 부탁드리고 틀린 부분 있으시면 댓글 부탁드립니다!
코드는
https://github.com/RowenKim/downExcel
GitHub - RowenKim/downExcel: SpringBoot, Poi library, Html, JAVA
SpringBoot, Poi library, Html, JAVA. Contribute to RowenKim/downExcel development by creating an account on GitHub.
github.com
참고해주세요!
'Back-end > Java' 카테고리의 다른 글
[JAVA] Java 기본인 Test 코드 작성(Feat.AssertJ )_김영한님 스프링 핵심 원리 - 기본편 (0) | 2023.05.28 |
---|---|
[JAVA] Naver 검색 API 사용법 (2) | 2023.05.28 |
[JAVA] ChatGPT API 사용하여 간단한 채팅 시스템 만들기 (0) | 2023.03.11 |
[JAVA] 기존 경로에 담겨있는 파일들 Zip 파일 만들기 (0) | 2023.02.20 |
Java SpringBoot 게시판 목록 페이징 처리하기 (0) | 2022.01.02 |