반응형
목차
화면에서 사용자가 체크한 row의 데이터들만 서버로 보내서 엑셀 다운로드 창을 브라우저에게 띄우게 하고 엑셀 다운로드 하는 로직
springBoot 2.7.7, jdk 11 version
view
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div class="contents">
<h2>엑셀 다운로드 예제</h2>
<div class="tbl scroll-x">
<table>
<caption>목록</caption>
<colgroup>
<col width="60px">
<col width="60px">
<col width="100px">
<col width="150px">
</colgroup>
<thead>
<tr>
<th scope="row">체크박스</th>
<th scope="row">순번</th>
<th scope="row">사원명</th>
<th scope="row">직업</th>
</tr>
</thead>
<tbody class="center">
<tr>
<td><input type="checkbox" class="checkbox"></td>
<td>kkh</td>
<td>김경호</td>
<td>가수</td>
</tr>
<tr>
<td><input type="checkbox" class="checkbox"></td>
<td>ljb</td>
<td>박완규</td>
<td>가수</td>
</tr>
<tr>
<td><input type="checkbox" class="checkbox"></td>
<td>jkh</td>
<td>정경화</td>
<td>가수</td>
</tr>
</tbody>
</table>
<button id="btn">엑셀 다운로드</button>
</div>
</div>
<script>
function downloadExcel() {
//데이터 담을 배열
var selectedData = [];
//class명이 checkbox인 친구들 루프 돌며 td 엘리먼트에서 텍스트를 가져온다.
$('.checkbox:checked').each(function() {
var rowData = $(this).closest('tr');
var fields = rowData.find('td');
//td에 표시된 데이터들을 JSON형식으로 세팅
var dataObject = {
id: fields.eq(1).text(),
name: fields.eq(2).text(),
job: fields.eq(3).text(),
};
//배열에 JSON 데이터 저장
selectedData.push(dataObject);
});
//엑셀다운로드 url + 데이터 인코딩한 값을 쿼리스트링으로 붙인 값으로 주소 변경
var downloadUrl = '/user/downloadExcel?selectedData=' + encodeURIComponent(JSON.stringify(selectedData));
window.location.href = downloadUrl;
}
$("#btn").on("click", function () {
downloadExcel();
});
</script>
</html>
의존성(gradle)
// poi
implementation 'org.apache.poi:poi:5.1.0' // xls
implementation 'org.apache.poi:poi-ooxml:5.1.0' //xlsx
Controller(VO버전)
본래 컨트롤러에는 비즈니스 로직이 없어야 하지만 여기선 예시니까 비즈니스 로직 서비스로 빼지 않았다.(귀찮아서)
@GetMapping("/downloadExcel")
//JSON타입의 문자열을 받는다.
public void downloadExcel(@RequestParam(name = "selectedData") String selectedData, HttpServletResponse response) throws IOException {
//ExcelVO타입의 list를 받는다.(ExcelVO는 id, name, job만 있는 VO다.)
List<ExcelVO> dataList = convertJsonToList(selectedData);
//엑셀파일 하나 생성
Workbook wb = new XSSFWorkbook();
//시트 하나 생성
Sheet sheet = wb.createSheet("test");
// header(상단 제목)
Row headerRow = sheet.createRow(0); //row 삽입
//row의 셀(열) 세팅
headerRow.createCell(0).setCellValue("아이디");
headerRow.createCell(1).setCellValue("이름");
headerRow.createCell(2).setCellValue("직업");
// body(헤더 아래 본문)
int rowNum = 1;
//리스트 루프 돌며 vo의 값으로 셀의 값 세팅
for (ExcelVO vo : dataList) {
Row row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(vo.getId());
row.createCell(1).setCellValue(vo.getName());
row.createCell(2).setCellValue(vo.getJob());
}
String fileName = "엑셀다운로드.xlsx";
//파일명이 한글이기에 인코딩
fileName = URLEncoder.encode(fileName, "UTF-8");
// HTTP 응답 설정(브라우저에게 파일다운로드 표시 요청)
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
// 엑셀 파일을 HTTP 응답 스트림에 쓰기
wb.write(response.getOutputStream());
wb.close();
}
//JSON 타입의 데이터를 ExcelVO타입의 List로 변환 후 반환
private List<ExcelVO> convertJsonToList(String jsonData) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(jsonData, new TypeReference<List<ExcelVO>>() {});
}
Controller(map 버전 + 키값 한글 매핑)
@GetMapping("/downloadExcel")
public void downloadExcel(@RequestParam(name = "selectedData") String selectedData, HttpServletResponse response) throws IOException {
//map 버전
List<Map<String, String>> dataList = convertJsonToList(selectedData);
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("test");
// header
Row headerRow = sheet.createRow(0);
int cellNum = 0;
for (String key : dataList.get(0).keySet()) {
//헤더값 한글 세팅(맵의 키값과 매핑되는 한글)
String headerName = convertToKorean(key);
headerRow.createCell(cellNum++).setCellValue(headerName);
}
// body
int rowNum = 1;
for (Map<String, String> data : dataList) {
Row row = sheet.createRow(rowNum++);
cellNum = 0;
//맵의 value로 셀 세팅
for (String key : data.keySet()) {
row.createCell(cellNum++).setCellValue(data.get(key));
}
}
String fileName = "엑셀다운로드.xlsx";
fileName = URLEncoder.encode(fileName, "UTF-8");
// HTTP 응답 설정
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
// 엑셀 파일을 HTTP 응답 스트림에 쓰기
wb.write(response.getOutputStream());
wb.close();
}
//JSON데이터를 String, String타입의 Map형식의 리스트로 변환 후 반환
private List<Map<String, String>> convertJsonToList(String jsonData) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(jsonData, new TypeReference<List<Map<String, String>>>() {});
}
// 키값을 한글로 변환하는 메서드
private String convertToKorean(String key) {
switch (key) {
case "rowNum":
return "순번";
case "id":
return "아이디";
case "name":
return "이름";
case "job":
return "직업";
// 추가 필드가 있을 경우 계속해서 매핑
default:
return key;
}
}
아래는 이 부분을 나름 모듈화 한 내용이다.
개인 스터디 기록을 메모하는 공간이라 틀린점이 있을 수 있습니다.
틀린 점 있을 경우 댓글 부탁드립니다.
반응형
'IT > development' 카테고리의 다른 글
[spring] spring excel download 모듈화 ver 2 (45) | 2024.01.14 |
---|---|
[spring] spring excel download 모듈화 ver 1 (41) | 2024.01.14 |
[IDE] IntelliJ jdk 버전 변경 (21) | 2023.12.30 |
[IDE] IntelliJ tomcat 한글 깨짐 조치 (22) | 2023.12.30 |
[mybatis] dynamic query template (30) | 2023.12.24 |
댓글