개발환경 : Spring Boot, Thymeleaf, javascript, html
ajax 를 이용해 csv 파일 다운로드를 구현하는 과정에서 데이터가 많아질수록 느려지고 실패하는 경우도 있었다.
이러한 이유는 csv 데이터는 String 형태로 "," 콤마로 구분해 데이터를 만들어 넘기는데
반복문이 많아질수록 서버가 죽을 위험이 있다. 그래서 더 좋은 방법을 구현하는 과정에서
Html 파일을 사용하여 다운받는 방법을 사용했다.
Html
<div>
<form th:id="downloadForm" th:method="post" th:action="@{Controller URL}"
th:autocomplete="off">
<input type="hidden" id="downloadStartDate" name="dateStart" />
<input type="hidden" id="downloadEndDate" name="dateEnd" />
<input type="hidden" id="downloadStartH" name="startH" />
<input type="hidden" id="downloadStartM" name="startM" />
<input type="hidden" id="downloadStartS" name="startS" />
<input type="hidden" id="downloadEndH" name="endH" />
<input type="hidden" id="downloadEndM" name="endM" />
<input type="hidden" id="downloadEndS" name="endS" />
<input type="hidden" id="downloadAni" name="ani" />
<input type="hidden" id="downloadUsid" name="usid" />
<input type="hidden" id="downloadHoliday" name="holiday" />
<input type="hidden" id="downloadWeek" name="week" />
<input type="hidden" id="downloadDnis" name="dnis" />
</form>
</div>
위와 같이 Controller 에서 받아 처리할 데이터를 Form 태그를 통해 Submit 을 한다.
넘길 파라미터가 존재하지 않을 경우 Form 태그만 사용하여 action 으로 던져도 가능하다.
Javascript
...
$("#downloadForm").submit();
...
버튼 클릭 이벤트를 통해 form 태그의 id 가 downloadForm 을 submit() 을 한다.
Controller.java
@PostMapping(value = "/full/download")
public String callListFullDownload(ModelMap model, HttpServletResponse response,
....
){
...데이터 처리
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Disposition","attachment;filename=callList.xls");
response.setContentType("application/vnd.ms-excel");
model.addAttribute("result", result);
return "contents/reporter/callList/ajax/callListExcel";
}
HttpServletResponse 을 활용해 Return 할 데이터의 Header 와 Content-Type 을 설정하여 Html 파일을 Return 한다.
Spring Boot 의 Return String 타입은 HTML 파일을 리턴하고 setContentType 을 통해
Return 되는 타입 형식은 Excel 형식으로 리턴한다.
Html 파일을 Return 하면서 ModelMap 에 저장된 result 값으로 그려진 후 다운로드가 받아진다.
Excel Html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<table border="1">
<thead>
<tr>
<th><strong>사이트</strong></th>
<th><strong>날짜</strong></th>
<th><strong>시간</strong></th>
<th><strong>USID</strong></th>
<th><strong>ANI</strong></th>
<th><strong>런처타입</strong></th>
<th><strong>DNIS</strong></th>
<th><strong>마지막트레이스코드</strong></th>
<th><strong>마지막트레이스코드이름</strong></th>
<th><strong>서비스이용수</strong></th>
<th><strong>상담사연결</strong></th>
</tr>
</thead>
<tbody>
<th:block th:each="list : ${result}">
<tr>
<td th:text="${list.site_name}"></td>
<td th:text="${list.en_date}"></td>
<td th:text="${list.en_time}"></td>
<td th:text="${list.usid}"></td>
<td th:text="${list.ani_mask}"></td>
<td th:text="${list.launcher_type}"></td>
<td th:text="${list.dnis}"></td>
<td th:text="${list.tracecode_last}"></td>
<td th:text="${list.tracecode_name}"></td>
<td th:text="${list.trace_count}"></td>
<td th:text="${list.fs_flag}"></td>
</tr>
</th:block>
<tr>
<td colspan="3">데이터가 없습니다.</td>
</tr>
</tbody>
</table>
</body>
</html>
Controller 에서 Html 파일을 리턴 후 result 에 담긴 데이터가 Html 파일에 그려지고 난 후
ContentType 에 의해 Excel 형식으로 파일이 다운로드 받아진다.