[Java] POI 라이브러리 사용 : 엑셀 다운로드 로직 구현하기
[Java] POI 라이브러리 사용 : 엑셀 다운로드 로직 구현하기
- 의존성 추가
Spring Boot 경우 build.gradle에 Gradle dependency 추가
compile group: 'org.apache.poi', name: 'poi', version: '3.13'
Spring 경우 pom.xml Maven dependency 추가
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.13-beta1</version>
</dependency>
- Haenny 엑셀 다운로드
다음과 같은 두 개의 클래스로 엑셀 다운로드 로직을 구현하였다.
참고로 엑셀에 입력될 데이터는 EgovMap이 아닌 VO List 형태를 전제로 구현하였다.
DownloadExcel.java
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DownloadExcel {
private static final Logger LOGGER = LoggerFactory.getLogger(DownloadExcel.class);
private HttpServletResponse response;
private HSSFWorkbook wb;
public DownloadExcel(String filename, HttpServletRequest request, HttpServletResponse response, HSSFWorkbook wb) {
this.response = response;
this.wb = wb;
try {
String browser = CommonVariable.getBrowser(request); // 브라우저 확인하는 메서드
String encodedFilename = null;
if (browser.equals("MSIE")) {
encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll(
"\\+", "%20");
} else if (browser.equals("Firefox")) {
encodedFilename = "\""
+ new String(filename.getBytes("UTF-8"), "8859_1") + "\"";
} else if (browser.equals("Opera")) {
encodedFilename = "\""
+ new String(filename.getBytes("UTF-8"), "8859_1") + "\"";
} else if (browser.equals("Chrome")) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < filename.length(); i++) {
char c = filename.charAt(i);
if (c > '~') {
sb.append(URLEncoder.encode("" + c, "UTF-8"));
} else {
sb.append(c);
}
}
encodedFilename = sb.toString();
} else {
throw new IOException("Not supported browser");
}
response.setHeader("Content-Disposition", "attachment; filename=" + encodedFilename);
if("Opera".equals(browser)){
response.setContentType("application/octet-stream;charset=UTF-8");
}
} catch (IOException e) {
LOGGER.error("[Excel Download Error]");
}
}
public void writeExcel(){
ServletOutputStream sos = null;
try{
sos = response.getOutputStream();
wb.write(sos);
sos.flush();
}catch(IOException e){
LOGGER.error("[Excel Download Error]");
}finally{
if(sos!=null){
try {
sos.close();
} catch (IOException e) {
LOGGER.error("[Excel Download Error]");
}
}
if(wb!=null){
try {
wb.close();
} catch (IOException e) {
LOGGER.error("[Excel Download Error]");
}
}
}
}
public CellStyle headStyle(){
HSSFFont font = wb.createFont();
font.setBold(true);
font.setColor(IndexedColors.WHITE.index);
CellStyle style = wb.createCellStyle();
style.setFont(font);
style.setWrapText(true);
style.setFillForegroundColor(IndexedColors.ROYAL_BLUE.index);
style.setFillPattern(CellStyle.SOLID_FOREGROUND);
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
return style;
}
public CellStyle bodyStyle(){
HSSFFont font = wb.createFont();
CellStyle style = wb.createCellStyle();
style.setFont(font);
style.setWrapText(true);
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
return style;
}
}
ExportExcelVOList.java
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
public class ExportExcelVOList {
private HttpServletRequest req;
private HttpServletResponse res;
protected HSSFSheet[] sheetArray;
protected HSSFWorkbook wb;
protected DownloadExcel downloadExcel;
protected String colN[];
protected CellStyle headStyle;
protected CellStyle bodyStyle;
public ExportExcelVOList(HttpServletRequest request, HttpServletResponse response) {
this.req = request;
this.res = response;
this.sheetArray = new HSSFSheet[1];
this.wb = new HSSFWorkbook();
if(CommonVariable.chkNull(request.getParameter("colN[]"))){
this.colN = request.getParameter("colN[]").split(",");
}
this.setExcelFormat();
}
/* 필수 exl.setListData 로 가져온 HSSFSheet를 넘겨줘야함 */
public void setSheetArray(int index, HSSFSheet st) {
sheetArray[index] = st;
}
/* 필수 모든 세팅이 완료된 후 엑셀 다운로드 받는 메소드 */
public void actionDownloadExcel() {
downloadExcel.writeExcel();
}
/* 파라메터로 넘어온 엑셀명 혹은 다운받은 일시를 파일명으로 엑셀파일 생성*/
private void setExcelFormat(){
long time = System.currentTimeMillis();
SimpleDateFormat day = new SimpleDateFormat("yyyyMMddhhmmss");
String excelnm = day.format(time);
this.downloadExcel = new DownloadExcel(excelnm+".xls", req, res, wb);
this.headStyle = downloadExcel.headStyle();
this.bodyStyle = downloadExcel.bodyStyle();
}
/* 컬럼 스타일 세팅 및 컬럼제목 입력*/
private void setColumnStyle(HSSFSheet st, HSSFRow title, int width, int addIdx){
for (int i = 0; i < colN.length; i++) {
title.createCell(i + addIdx).setCellValue(colN[i].replaceAll(">=", ">="));
title.getCell(i + addIdx).setCellStyle(headStyle);
st.setColumnWidth(i + addIdx, width);
}
}
/* VO data를 파라메터로 생성할 각 시트에 세팅*/
public HSSFSheet setDataToExcelList(List<?> data, String sheetName) {
HSSFSheet st = null;
try {
st = wb.createSheet(sheetName);
HSSFRow titleRow = st.createRow(0);
titleRow.setHeight((short) 400);
setColumnStyle(st, titleRow, 6000, 0); // colN을 이용한 컬럼명 처리
for (int i = 0; i < data.size(); i++) {
HSSFRow row = st.createRow(st.getLastRowNum() + 1);
row = setRowData(row, data.get(i), 0);
}
} catch (Exception e) {
e.printStackTrace();
}
return st;
}
/* VO data를 파라메터로 해당 데이터 셀에 입력*/
private HSSFRow setRowData(HSSFRow row, Object data, int stIdx) throws IllegalArgumentException, IllegalAccessException{
int edIdx = 0;
for(Field field : data.getClass().getDeclaredFields()) {
field.setAccessible(true);
Object value = field.get(data);
row.createCell(stIdx+edIdx).setCellValue(value.toString());
edIdx++;
}
for(int i=0; i<edIdx; i++){
row.getCell(stIdx+i).setCellStyle(bodyStyle);
}
return row;
}
}
- Controller 사용방법
1. 단일 시트인 경우
@RequestMapping(value="/excel", method = RequestMethod.POST, produces="text/plain;Charset=UTF-8")
public void exceldownload(MultipartHttpServletRequest req, HttpServletResponse res) throws Exception {
// 파라메터로 받아온 key값(조회 조건)
String key = req.getParameter("key").replaceAll(""","");
try {
// DB에 key값에 일치하는 데이터 리스트 조회
List<ExcelVO> list = service.getExcelList(key);
// 생성자함수로 생성 후 초기 세팅
ExportExcelVOList exl = new ExportExcelVOList(req, res);
// 파라메터 : 조회한 리스트, 시트명
HSSFSheet st = exl.setDataToExcelList(list, "sheet1");
exl.setSheetArray(0, st); // 1개의 시트 사용하는 경우
exl.actionDownloadExcel(); // 엑셀 다운로드
} catch (Exception e) {
e.printStackTrace();
}
}
2. 복수 시트인 경우
@RequestMapping(value="/excel", method = RequestMethod.POST, produces="text/plain;Charset=UTF-8")
public void exceldownload(MultipartHttpServletRequest req, HttpServletResponse res) throws Exception {
String key = req.getParameter("key").replaceAll(""","");
try {
List<ExcelVO> list = service.getExcelList(key);
ExportExcelVOList exl = new ExportExcelVOList(req, res);
for(int i=0; i<2; i++){ // 3개의 sheet 생성할 경우
HSSFSheet st = exl.setDataToExcelList(list, "sheet"+i);
exl.setSheetArray(i, st);
}
exl.actionDownloadExcel(); // 엑셀 다운로드
} catch (Exception e) {
e.printStackTrace();
}
}
엑셀 다운로드에 해당하는 DownloadExcel.java 와 ExportExcelVOList.java는 사용중인 코드를 그대로 복사해서 넣은 것이다.
그러니 모르는게 있다면 언제든 댓글^__^
아 ! 이번 게시물은 VO List 데이터로 엑셀 데이터를 입력했는데, 다음에는 EgovMap 데이터로 엑셀 다운로드 받는 게시물을 가져오겠다.
CommonVariable Class 추가 - 2022.02.11
CommonVariable 같은 경우는 제가 임의로 만든 클래스이고, 공통적으로 쓰이는 변수나 메서드를 담은 클래스입니다.
위에서 사용한 getBrowser 와 chkNull 메서드는 브라우저를 체크하는 메서드, null 체크 메서드로 getBrowser 메서드는 다음과 같이 구성되어있습니다.
public static String getBrowser(HttpServletRequest req) {
String header = request.getHeader("User-Agent");
if (header.indexOf("MSIE") > -1) {
return "MSIE";
} else if (header.indexOf("Chrome") > -1) {
return "Chrome";
} else if (header.indexOf("Opera") > -1) {
return "Opera";
} else if (header.indexOf("Firefox") > -1) {
return "Firefox";
} else if (header.indexOf("Mozilla") > -1) {
if (header.indexOf("Firefox") > -1) {
return "Firefox";
}else{
return "MSIE";
}
}
return "MSIE";
}
'JAVA > Java' 카테고리의 다른 글
[Java] POI Excel CellStyle 버전 업 후 Deprecated 된 속성 알아보기 (0) | 2022.11.15 |
---|---|
[Java] 추상클래스와 인터페이스 차이 (0) | 2022.11.15 |
[Java] Spring Controller 파라미터 값 가져오기(HttpServletRequest, @RequestParam, @RequestBody, @ModelAttribute) (0) | 2022.11.15 |
[Java] SimpleCaptcha를 이용한 이미지 보안문자 생성하기 (0) | 2022.11.15 |
[Java] 특정문자로 문자열 나누기 split 사용방법과 주의점 (0) | 2022.11.15 |
[Java] StartsWith/EndWith : 문자열의 시작/끝 부분과 특정 문자열이 일치하는지 확인하기 (0) | 2022.11.15 |
[Java] StringBuffer append("a"+"b") 메모리는 어떻게 할당될까? (0) | 2022.11.15 |
[Java] String, StringBuffer, StringBuilder의 차이점 (0) | 2022.11.15 |