안녕하세요~! ㅎㅎ
오늘은 JavaScript를 이용해서
웹단의 표를 엑셀로 바로 다운로드 받는 소스를 기록하고자합니다.
우선 다른 포스팅을 봤는데 다들 너무 잘 작성해서 좋았지만 그래도 제 방식대로 작성되어있는 것이 없어서
제 방식대로 기록을 남겨보겠습니다.
1. JSP / HMTL 에 그려질 표
예시 화면입니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TEST PAGE</title>
</head>
<body>
<h1>Hello world!!</h1>
<div id='downTbl'>
<table class="" border="1" id='tbl1'>
<colgroup>
<col width="3%">
<col width="130">
<col width="130">
<col width="130">
</colgroup>
<thead>
<tr>
<th>no</th>
<th>title</th>
<th>count1</th>
<th>count2</th>
<th>total amount</th>
<th>percent</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<button class="btn_txt_green" type="button">1</button>
</td>
<td>book</td>
<td data-type="Number" data-style='Number'>5,944,728</td>
<td data-type="Number">32</td>
<td data-type="Number">5,944,760</td>
<td data-type="Number">0.99</td>
</tr>
<tr>
<td>
<button class="btn_txt_green" type="button">2</button>
</td>
<td>coffee</td>
<td>5,918,064</td>
<td>45</td>
<td>5,918,109</td>
<td>0.99</td>
</tr>
</tbody>
</table>
</div>
<button id='btn'>download</button>
</body>
</html>
<script src='testJS.js'></script>
소스먼저 확인 한다음 설명드리겠습니다.
2. JavaScript 다운로드 구현부
window.addEventListener("load",function(){
document.getElementById('btn').addEventListener('click', function(){
_excelDown('엑셀테스트.xls','시트1')
})
})
/**
* 엑셀 다운로드
* @param fileName 엑셀파일명 (ex. excel.xls)
* @param sheetName 시트명
*/
function _excelDown(fileName, sheetName) {
let sheetHtml = document.getElementById('downTbl').innerHTML;
let innerExcel = '';
innerExcel+=`
<html xmlns:x="urn:schemas-microsoft-com:office:excel">
<head>
<meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8">
<xml>
<x:ExcelWorkbook>
<x:ExcelWorksheets>
<x:ExcelWorksheet>
<x:Name>${sheetName}</x:Name>
<x:WorksheetOptions><x:Panes></x:Panes></x:WorksheetOptions>
</x:ExcelWorksheet>
</x:ExcelWorksheets>
</x:ExcelWorkbook>
</xml>
</head>
<body>
${sheetHtml}
</body>
</html>
`;
/* 데이터 타입 지정 : 엑셀로 지정한다. */
let data_type = 'data:application/vnd.ms-excel';
/* blob 객체를 생성한다. 이때 XML 형식으로 되어있는 innerExcel을 배열로 넣어준다.
* 주로 배열형태의 DOMString 형태로 처음에 인자를 받는다.
* 두번째로 옵션을 지정해주는것인다. MIME로 지정해준다.
* */
let blob = new Blob(
[innerExcel]
, {
type : "application/csv;charset=utf-8;"
}
);
/* blob이 다운로드 이벤트가 일어나지기 위한 임시 객체 a를 만든다. */
let tmpEle = window.document.createElement('a');
/* blob을 다운로드 시킬 URL을 임시로 만든 a태그 안에 href를 셋팅해준다. */
tmpEle.href = window.URL.createObjectURL(blob);
/* 임시태그받는 파일이름을 파라미터로 받아온 파일이름을 넣어준다. */
tmpEle.download = fileName;
/* 지금껏 설정한 a태그를 document의 바디 안에 임시로 삽입한다. */
document.body.appendChild(tmpEle);
/* 그리고 일부러 클릭이 되어지는 이벤트를 넣어서 자동으로 다운로드되어지는것 처럼 연출한다. */
tmpEle.click();
/* 클릭이벤트 종료 후 임시로 만들어진 a태그는 삭제한다. */
document.body.removeChild(tmpEle);
}

우아~ 저도 이번에 주석을 달면서 하나하나 공부했더니 도움이 되었어요! ㅎㅎㅎ
왜 많은 사람들이 다 하단을 공통적으로 저렇게 작성했는지 바로 알겠더라구요 ㅎㅎ
그리고 다른방법은 없나 고민도 해보는 좋은 시간도 되었어요
여튼 저는 저만의 스타일로 작성했습니다.
다운로드 눌렀을때,
그리고 정상적으로
1 : 파일명 정상
2 : 데이터 정상
3 : 시트명 정상
모두 정상적으로 나왔습니다.
3. 마치며
다른 글을 보고 수정한점 :
개인적으로 함수형 언어를 사용하거나 그럴때 파라미터값 3개이상 넣는것을 별로 선호하지 않아서 딱 해당 값에서 필요한 받아올 인자인 파일명과 시트명을 받아오게끔 했습니다.
예를 들어서 2022_3분기_##부서_예산책정안.xls로 다운을 받아야하고, 또 파일을 열었을때 시트에는 ##부서 또는 3분기보고 등 시트이름이 자동적으로 해당 파일이나 상황에 맞게 들어가야하기 때문이라고 생각했습니다.
그리고 가져올 값은 어짜피 div태그에서 가져오게 될텐데 또 그걸 파라미터로 가져온다..는건 이해가 되지않았습니다.
그떄그때 필요한 id를 가져오는것이 낫지 않을까라는 생각이 들었고 만약 수 많은 엑셀 데이터중 하나의 함수로 공통화를 하고자 한다면
이런식으로 했을것같습니다.
그리고 제이쿼리를 조금 싫어하는 경향이있어서 대부분 바닐라 JS를 이용했습니다.
그리고 html += 이렇게 추가해주는 부분도 조금 가독성이라던가 수정할때 번거로운 점이있어서 한번에 작성했습니다.
그리고 Table 자체의 ID를 가져온다면 아마도 다운받은 결과가 깨지게 될텐데요
Table을 Div태그로 한번 감싸주시길 바랍니다. ㅎㅎ 물론 제 소스 참고해서 사용하신다면요
그리고 요즘 IE가 없어지는 바람에 IE의 다운로드 로직을 없앴습니다.
해당 로직에 대해서는 애초에 IE가 내 웹페이지를 오게된다면 경고를 주고 일부기능 제한이라고 경고하고
그에 대한 개발을 더 안하는 쪽으로 생각했습니다.
이것으로 바닐라JS 엑셀 다운로드 하는 기능을 제 입맛에 맛게 소스를 수정했습니다.
언제까지나 개인의 기록 및 참고용이지 이게 맞다! 내껄써라! 이건 아님을 재차 강조드립니다.
그러니 너그러히 봐주시기 바랍니다. ㅠㅠㅠ

긴글 읽어주셔서 감사합니다.!!!
댓글