Spring java excel download 스프링 엑셀 다운 poi
SRPING MVC 이미지
안녕하세요. 웹 개발일을 하다 보면 엑셀 파일을 요청받을 일들이 있어요.
SPRING에서는 아파치 소프트웨어 재단에서 만든 POI를 사용할 수 있어요.
마이크로소프트 오피스 파일들을 읽고 쓰는 기능을 제공하는데요. 워드, 엑셀, 파워포인트 파일을 지원하고 있어요. 최근 OFFICE OPEN XML FILE FORMATS(*. DOCX,*. XLSX,*. PPTX)등 지원 파일을 늘려가고 있다고 해요.
처음 메이븐 설정을 해요.
<!-- 엑셀파일 -->
<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.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
SERVLET-CONTEXT.XML 파일 내용을 찾아보면 InternalResourceViewResolver가 선언되어 있을거에요.
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
JSP페이지로 이름을 매핑해주는것인데 대부분 설정이 되어 있을 거예요.
저희가 받아야 할 건 JSP페이지가 아니에요.
XmlViewResolver를 설정해줘야 해요. 조금 귀찮긴 한데 한번 만들어 놓으면 다른 프로젝트에도 복사해서 사용하면 돼요.
<beans:bean id="viewResolver1" class="org.springframework.web.servlet.view.XmlViewResolver">
<beans:property name="order" value="1"/>
<beans:property name="location" value="/WEB-INF/views.xml"/>
</beans:bean>
views.xml파일위치
views.xml파일을 만들어요.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="mr001_exceldownload_View" class="com.sms2019.excel.mr001_exceldownload_View" />
</beans>
그리고 소스파일에 views.properties 추가를 해요.
views.properties
mr001_exceldownload_View.(class)=com.sms2019.excel.mr001_exceldownload_View
컨트롤러 부분에 요청받는 부분을 만들어요.
@RequestMapping(value = "/g402_excel_download", method = RequestMethod.GET)
public ModelAndView g402_excel_download(HttpServletRequest request, Model model) throws Exception {
Util_list_convert smsp=Util_list_convert.getInstance();
smsp.print_String("/gp/g402_excel_download");
Map<String, String[]> paramMap=request.getParameterMap();
paramMap.forEach(
(key, value) -> smsp.print_String(key + " : " + value[0])
);
Iterator keyData = paramMap.keySet().iterator();
CommonData dto = new CommonData();
paramMap.forEach(
(key, value) -> {dto.put(key, value[0]);
smsp.print_String(key + " : " + value[0]);
model.addAttribute(key,value[0].toString());
});
CommonData data_box = new CommonData();
List Title_list = new ArrayList();
Title_list.add("번호");
Title_list.add("품목명");
Title_list.add("규격");
Title_list.add("파트");
Title_list.add("수량");
Title_list.add("팀");
List Title_list_coll = new ArrayList();
Title_list_coll.add("rownum");
Title_list_coll.add("item_name");
Title_list_coll.add("item_standard");
Title_list_coll.add("part_division_text");
Title_list_coll.add("quantity");
Title_list_coll.add("team_code_text");
dto.put("exceldown","exceldown");
List<Map<String, Object>> list = z_service.select(dto,"Gp2018_Mapper.g402_list_select");
ModelAndView mav = new ModelAndView("mr001_exceldownload_View");
mav.addObject("Title_list", Title_list);
mav.addObject("Title_list_coll", Title_list_coll);
mav.addObject("list", list);
mav.addObject("Filename", "주문목록");
return mav;
}
엑셀 파일 데이터를 만들어요 db에서 읽어와도 좋고요 엑셀 윗부분을 요청 시 받아와도 되고요 전 컨트롤러를 각각 만들어서 써요. 그래서 타이틀이랑 항목 칼럼 이름 그리고 데이터 그리고 파일 이름 넣어요.
그럼 MadelAndView에 적힌 부분으로 호출이 되는데요.
package com.danawa.excel;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.view.document.AbstractExcelView;
import com.danawa.domain.CommonData;
import com.danawa.util.Util_list_convert;
@Controller
public class mr001_exceldownload_View extends AbstractExcelView {
@Override
protected void buildExcelDocument(Map<String, Object> model,
HSSFWorkbook workbook, HttpServletRequest request, HttpServletResponse response)
throws Exception {
Util_list_convert smsp=Util_list_convert.getInstance();
smsp.print_String("Common_exceldownload");
String Filename = (String)model.get("Filename");
String fileName = Filename+".xls";
fileName = URLEncoder.encode(fileName,"UTF-8");
response.setContentType("application/ms-excel; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition","attachment; filename="+fileName);
// get data model which is passed by the Spring container
List<String> Title_list = (List<String>) model.get("Title_list");
List<String> Title_list_coll = (List<String>) model.get("Title_list_coll");
List<CommonData> list = (List<CommonData>) model.get("list");
// create a new Excel sheet
HSSFSheet sheet = workbook.createSheet("sheet1");
sheet.setDefaultColumnWidth(30);
// create style for header cells
CellStyle style = workbook.createCellStyle();
CellStyle centerstyle = workbook.createCellStyle();
CellStyle centerbluestyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setFontName("Arial");
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
font.setColor(HSSFColor.WHITE.index);
// style.setFillForegroundColor(HSSFColor.BLACK.index);
// style.setFillPattern(CellStyle.SOLID_FOREGROUND);
style.setBorderBottom (HSSFCellStyle.BORDER_THIN);
style.setBottomBorderColor (HSSFColor.BLACK.index);
style.setBorderLeft (HSSFCellStyle.BORDER_THIN);
style.setLeftBorderColor (HSSFColor.BLACK.index);
style.setBorderRight (HSSFCellStyle.BORDER_THIN);
style.setRightBorderColor (HSSFColor.BLACK.index);
style.setBorderTop (HSSFCellStyle.BORDER_THIN);
style.setTopBorderColor (HSSFColor.BLACK.index);
//style.setFont(font);
//centerstyle.setFillForegroundColor(HSSFColor.WHITE.index);
//centerstyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
centerstyle.setAlignment(CellStyle.ALIGN_CENTER);
centerstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
centerstyle.setBottomBorderColor(HSSFColor.BLACK.index);
centerstyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
centerstyle.setLeftBorderColor(HSSFColor.BLACK.index);
centerstyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
centerstyle.setRightBorderColor(HSSFColor.BLACK.index);
centerstyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
centerstyle.setTopBorderColor(HSSFColor.BLACK.index);
centerbluestyle.setFillForegroundColor(HSSFColor.BLACK.index);
centerbluestyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
centerbluestyle.setAlignment(CellStyle.ALIGN_CENTER);
centerbluestyle.setFillBackgroundColor(HSSFColor.BLACK.index);
centerbluestyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
centerbluestyle.setBottomBorderColor(HSSFColor.BLACK.index);
centerbluestyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
centerbluestyle.setLeftBorderColor(HSSFColor.BLACK.index);
centerbluestyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
centerbluestyle.setRightBorderColor(HSSFColor.BLACK.index);
centerbluestyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
centerbluestyle.setTopBorderColor(HSSFColor.BLACK.index);
centerbluestyle.setFont(font);
// create header row
HSSFRow header = sheet.createRow(0);
int cellCount;
cellCount=0;
int columns_length=0;
//제목 값 세팅 한다.
for(String item : Title_list){
header.createCell(cellCount).setCellValue(item);
header.getCell(cellCount).setCellStyle(centerbluestyle);
cellCount++;
columns_length++;
}
// create data rows
int rowCount = 1;
String sitem_name = null;
String item_standard = null;
String sitem_name_replace=null;
Iterator list_object = list.iterator();
while (list_object.hasNext()) {
CommonData e_object = (CommonData) list_object.next();
HSSFRow aRow = sheet.createRow(rowCount++);
cellCount=0;
for(String item : Title_list_coll){
String value = e_object.get(item);
smsp.print_String("item : " + value);
aRow.createCell(cellCount).setCellValue(value);
aRow.getCell(cellCount).setCellStyle(centerstyle);
cellCount++;
}
}
for(int ni=1;ni<=sheet.getLastRowNum();ni++)
{
sheet.getRow(ni).setHeightInPoints((float)20);
}
autoSizeColumns(sheet,sheet.getRow(0).getLastCellNum());
}
private void autoSizeColumns(HSSFSheet sheetData, int maxColNum) {
try {
// Autosize columns
int width = 0;
for (int col = 0; col < maxColNum; col++) {
sheetData.autoSizeColumn(col);
int cwidth = sheetData.getColumnWidth(col);
cwidth += 500;
sheetData.setColumnWidth(col, cwidth);
width += cwidth;
}
// calculate zoom factor
int nominator = 45000 * 100 / width;
if (nominator < 100)
sheetData.setZoom(nominator, 100);
} catch (Exception he) {
// No UI, no autosize :(
}
}
}
이렇게 엑셀 내용을 채워 엑셀 파일이 만들어져요.
String Filename = (String)model.get("Filename");
String fileName = Filename+".xls";
fileName = URLEncoder.encode(fileName,"UTF-8");
response.setContentType("application/ms-excel; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition","attachment; filename="+fileName);
파일 이름을 설정하고 utf8로 다운로드돼요.
List<String> Title_list = (List<String>) model.get("Title_list");
List<String> Title_list_coll = (List<String>) model.get("Title_list_coll");
List<CommonData> list = (List<CommonData>) model.get("list");
엑셀 파일의 항목 타이틀과 각 항목의 column의 이름 그리고 데이터 받아와요.
HSSFSheet sheet = workbook.createSheet("sheet1");
sheet.setDefaultColumnWidth(30);
sheet를 만들어요. 만들 때 이름을 정해줄 수 있어요. 전 sheet1이라고 했어요.
// create style for header cells
CellStyle style = workbook.createCellStyle();
CellStyle centerstyle = workbook.createCellStyle();
CellStyle centerbluestyle = workbook.createCellStyle();
cell 스타일을 미리 만들었어요. 단순해요. style는 흰색의 배경에 검은색의 테두리 선을 가진 것이고요. centerstyle는 중앙 정렬한 흰색 배경에 검은색 테두리 구요. centerbluestyle는 중앙 정렬에 파란 배경을 과 검은색 테두리를 가진 스타일이에요.
style.setBorderBottom (HSSFCellStyle.BORDER_THIN);
style.setBottomBorderColor (HSSFColor.BLACK.index);
style.setBorderLeft (HSSFCellStyle.BORDER_THIN);
style.setLeftBorderColor (HSSFColor.BLACK.index);
style.setBorderRight (HSSFCellStyle.BORDER_THIN);
style.setRightBorderColor (HSSFColor.BLACK.index);
style.setBorderTop (HSSFCellStyle.BORDER_THIN);
style.setTopBorderColor (HSSFColor.BLACK.index);
centerstyle.setAlignment(CellStyle.ALIGN_CENTER);
centerstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
centerstyle.setBottomBorderColor(HSSFColor.BLACK.index);
centerstyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
centerstyle.setLeftBorderColor(HSSFColor.BLACK.index);
centerstyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
centerstyle.setRightBorderColor(HSSFColor.BLACK.index);
centerstyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
centerstyle.setTopBorderColor(HSSFColor.BLACK.index);
centerbluestyle.setFillForegroundColor(HSSFColor.BLACK.index);
centerbluestyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
centerbluestyle.setAlignment(CellStyle.ALIGN_CENTER);
centerbluestyle.setFillBackgroundColor(HSSFColor.BLACK.index);
centerbluestyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
centerbluestyle.setBottomBorderColor(HSSFColor.BLACK.index);
centerbluestyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
centerbluestyle.setLeftBorderColor(HSSFColor.BLACK.index);
centerbluestyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
centerbluestyle.setRightBorderColor(HSSFColor.BLACK.index);
centerbluestyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
centerbluestyle.setTopBorderColor(HSSFColor.BLACK.index);
centerbluestyle.setFont(font);
직관적으로 만들어놓아서 대충 알아보실 거 같아요. 소스량을 줄이려면 함수를 만들면 되겠죠? 그건 직접 해보세요 ^^
Font font = workbook.createFont();
font.setFontName("Arial");
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
font.setColor(HSSFColor.WHITE.index);
폰트를 따로 선언해서 사용해야 할 일이 있을 경우엔 폰트도 추가해주세요 전 타이틀 부분은 폰트를 다르게 했어요 흰색으로요. ^^
HSSFRow header = sheet.createRow(0);
첫 번째 로우를 만들고요
int cellCount;
cellCount=0;
int columns_length=0;
//제목 값 세팅 한다.
for(String item : Title_list){
header.createCell(cellCount).setCellValue(item);
header.getCell(cellCount).setCellStyle(centerbluestyle);
cellCount++;
columns_length++;
}
첫번째 행에 항목 타이틀 값들을 넣어줘요...
// create data rows
int rowCount = 1;
String sitem_name = null;
String item_standard = null;
String sitem_name_replace=null;
Iterator list_object = list.iterator();
while (list_object.hasNext()) {
CommonData e_object = (CommonData) list_object.next();
HSSFRow aRow = sheet.createRow(rowCount++);
cellCount=0;
for(String item : Title_list_coll){
String value = e_object.get(item);
smsp.print_String("item : " + value);
aRow.createCell(cellCount).setCellValue(value);
aRow.getCell(cellCount).setCellStyle(centerstyle);
cellCount++;
}
}
컨트롤러에서 넘겼던 칼럼 항목 이름을 순으로 위치로 해서 셀에 넣어요.
이상으로 엑셀 파일 다운로드 관련해서 정리해보았습니다.