<%
response.setHeader("Content-Type", "application/vnd.ms-xls");
response.setHeader("Content-Disposition", "inline; filename=viewcount-excel.xls");
%>
jsp에서 html table을 excel 파일로 변환하는 것은 매우 간단하다.
상단에 헤더값 Content-Type을 application/vnd.ms.[원하는 엑셀확장자]으로 선언하고 Content-Disposition값에 다운로드할 파일의 이름(filename=)을 적어주면 해결된다.
하지만 엑셀 형식 중 .xlsx파일의 경우에는 파일이 깨졌다는 메시지와 함께 다운로드가 제대로 되지 않는다.
일반적인 MIME 유형
.aac | AAC audio | audio/aac |
.abw | AbiWord document | application/x-abiword |
.apng | Animated Portable Network Graphics (APNG) image | image/apng |
.arc | Archive document (multiple files embedded) | application/x-freearc |
.avif | AVIF image | image/avif |
.avi | AVI: Audio Video Interleave | video/x-msvideo |
.azw | Amazon Kindle eBook format | application/vnd.amazon.ebook |
.bin | Any kind of binary data | application/octet-stream |
.bmp | Windows OS/2 Bitmap Graphics | image/bmp |
.bz | BZip archive | application/x-bzip |
.bz2 | BZip2 archive | application/x-bzip2 |
.cda | CD audio | application/x-cdf |
.csh | C-Shell script | application/x-csh |
.css | Cascading Style Sheets (CSS) | text/css |
.csv | Comma-separated values (CSV) | text/csv |
.doc | Microsoft Word | application/msword |
.docx | Microsoft Word (OpenXML) | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
.eot | MS Embedded OpenType fonts | application/vnd.ms-fontobject |
.epub | Electronic publication (EPUB) | application/epub+zip |
.gz | GZip Compressed Archive | application/gzip |
.gif | Graphics Interchange Format (GIF) | image/gif |
.htm, .html | HyperText Markup Language (HTML) | text/html |
.ico | Icon format | image/vnd.microsoft.icon |
.ics | iCalendar format | text/calendar |
.jar | Java Archive (JAR) | application/java-archive |
.jpeg, .jpg | JPEG images | image/jpeg |
.js | JavaScript | text/javascript |
.json | JSON format | application/json |
.jsonld | JSON-LD format | application/ld+json |
.mid, .midi | Musical Instrument Digital Interface (MIDI) | audio/midi, audio/x-midi |
.mjs | JavaScript module | text/javascript |
.mp3 | MP3 audio | audio/mpeg |
.mp4 | MP4 video | video/mp4 |
.mpeg | MPEG Video | video/mpeg |
.mpkg | Apple Installer Package | application/vnd.apple.installer+xml |
.odp | OpenDocument presentation document | application/vnd.oasis.opendocument.presentation |
.ods | OpenDocument spreadsheet document | application/vnd.oasis.opendocument.spreadsheet |
.odt | OpenDocument text document | application/vnd.oasis.opendocument.text |
.oga | Ogg audio | audio/ogg |
.ogv | Ogg video | video/ogg |
.ogx | Ogg | application/ogg |
.opus | Opus audio in Ogg container | audio/ogg |
.otf | OpenType font | font/otf |
.png | Portable Network Graphics | image/png |
Adobe Portable Document Format (PDF) | application/pdf | |
.php | Hypertext Preprocessor (Personal Home Page) | application/x-httpd-php |
.ppt | Microsoft PowerPoint | application/vnd.ms-powerpoint |
.pptx | Microsoft PowerPoint (OpenXML) | application/vnd |
.rar | RAR archive | application/vnd.rar |
.rtf | Rich Text Format (RTF) | application/rtf |
.sh | Bourne shell script | application/x-sh |
.svg | Scalable Vector Graphics (SVG) | image/svg+xml |
.tar | Tape Archive (TAR) | application/x-tar |
.tif, .tiff | Tagged Image File Format (TIFF) | image/tiff |
.ts | MPEG transport stream | video/mp2t |
.ttf | TrueType Font | font/ttf |
.txt | Text, (generally ASCII or ISO 8859-n) | text/plain |
.vsd | Microsoft Visio | application/vnd.visio |
.wav | Waveform Audio Format | audio/wav |
.weba | WEBM audio | audio/webm |
.webm | WEBM video | video/webm |
.webp | WEBP image | image/webp |
.woff | Web Open Font Format (WOFF) | font/woff |
.woff2 | Web Open Font Format (WOFF) | font/woff2 |
.xhtml | XHTML | application/xhtml+xml |
.xls | Microsoft Excel | application/vnd.ms-excel |
.xlsx | Microsoft Excel (OpenXML) | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
.xml | XML | application/xml |
.xul | XUL | application/vnd.mozilla.xul+xml |
.zip | ZIP archive | application/zip |
.3gp | 3GPP audio/video container | video/3gpp |
.3g2 | 3GPP2 audio/video container | video/3gpp2 |
.7z | 7-zip archive | application/x-7z-compressed |
MIME 미디어 유형의 공식 레지스트리를 살펴보니 엑셀 형식중 xlsx는 Content-Type을 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet으로 변경해야 했다.
그러나 실제로 적용을 하고 다운로드를 해봤지만 형식이 잘못 되었다는 메시지와 함께 파일이 올바르게 열리지 않았다.
그래서 나는 javascript로 html을 xlsx로 변환하는 방법을 찾아보게 되었다.
SheetJS를 이용한 HTML을 EXCEL 파일로 변환하는 방법
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Html Table to Excel xlsx</title>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.14.3/xlsx.full.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.8/FileSaver.min.js"></script>
<script>
function s2ab(s) {
var buf = new ArrayBuffer(s.length); //convert s to arrayBuffer
var view = new Uint8Array(buf); //create uint8array as viewer
for (var i=0; i<s.length; i++) view[i] = s.charCodeAt(i) & 0xFF; //convert to octet
return buf;
}
function exportExcel(){
var wb = XLSX.utils.book_new();
var newWorksheet = excelHandler.getWorksheet();
XLSX.utils.book_append_sheet(wb, newWorksheet, excelHandler.getSheetName());
var wbout = XLSX.write(wb, {bookType:'xlsx', type: 'binary'});
saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), excelHandler.getExcelFileName());
}
$(document).ready(function() {
$("#excelFileExport").click(function(){
exportExcel();
});
});
</script>
<script>
var excelHandler = {
getExcelFileName : function(){
return 'excel_download.xlsx';
},
getSheetName : function(){
return 'Html Table to Excel';
},
getExcelData : function(){
return document.getElementById('tableData');
},
getWorksheet : function(){
return XLSX.utils.table_to_sheet(this.getExcelData());
}
}
</script>
</head>
<body>
<input type="button" id="excelFileExport" value="엑셀 다운로드" />
<table id="tableData" border="1" >
<thead>
<tr>
<th style="text-align: center; width: 200px;">이름</th>
<th style="text-align: center; width: 200px;">국어</th>
<th style="text-align: center; width: 200px;">영어</th>
<th style="text-align: center; width: 200px;">합계</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: right">철수</td>
<td style="text-align: right">90</td>
<td style="text-align: right">80</td>
<td style="text-align: right"><b>170</b></td>
</tr>
<tr>
<td style="text-align: right">영이</td>
<td style="text-align: right">50</td>
<td style="text-align: right">40</td>
<td style="text-align: right"><b>90</b></td>
</tr>
<tr>
<td style="text-align: right">희철</td>
<td style="text-align: right">100</td>
<td style="text-align: right">40</td>
<td style="text-align: right"><b>140</b></td>
</tr>
</tbody>
</table>
</body>
</html>
SheetJs는 복잡한 스프레드 시트에서 데이터를 추출해 최신 소프트웨어에서 모두 작동하게끔 도와주는 오픈 소스이다.
먼저 html table을 만든 후에 id값을 주고 다운로드 버튼을 누르면 테이블의 셀값을 읽어서 blob형식으로 파일저장을 한다.
셀마다 스타일링을 하고 싶어 옵션을 찾아봤는데 프로 버전을 사용해야 셀에 스타일링을 주거나 성능향상이 가능하다고 하니 이점은 참고 하기 바란다.
참고한 글
https://eblo.tistory.com/84
https://git.sheetjs.com/SheetJS/sheetjs