티스토리 뷰
HTML Table을 엑셀로 내보내기 : Export to excel sheet on client side
serpiko 2015. 4. 2. 17:17HTML Table을 엑셀로 저장하기 : Export to excel sheet on client side
1. <A> 엘리먼트의 download 속성을 이용하여 저장하기.
2. <A> 엘리먼트의 download속성과 URL에 data타입을 사용하기, 엑셀 파일 이름 지정하기.
3. jquery.battatech.excelexport 라이브러리를 사용하기.
4. jquery.battatech.excelexport 라이브러리를 사용하여 파일이름 지정하기.
5. jquery.battatech.excelexport 라이브러리를 사용하여 파일이름 지정하기2.
1. <A> 엘리먼트의 download 속성을 이용하여 저장하기.
<!DOCTYPE html> <html lang="en"> <head> <meta name="Author" content="serpiko@hanmail.net" /> <meta name="description" content="http://serpiko.tistory.com" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <!--<meta name="viewport" content="width=device-width, initial-scale=1">--> <meta name="format-detection" content="telephone=no" /> <link rel="styleesheet" type="text/css" href="" /> <link rel="shortcut icon" href="" /> <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script> <title>Document</title> <style> * { box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; } table{ width: 650px; text-align: center; border: 1px solid black; } </style> </head> <body> <div id="wrap"> <table id='tblExport'> <thead> <tr> <th>No</th> <th>Title</th> <th>Type</th> <th>Author</th> <th>URL</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>SAP : Study And Programming</td> <td>Blog</td> <td style='background-color: LightBlue;'>Serpiko</td> <td>http://serpiko.tistory.com/</td> </tr> <tr> <td>2</td> <td>Twitter</td> <td>SNS</td> <td>Obvious, LLC</td> <td>https://www.twitter.com/</td> </tr> <tr> <td>3</td> <td>Instagram</td> <td>SNS</td> <td>Kevin Systrom, Mike Krieger</td> <td>https://instagram.com/</td> </tr> </tbody> </table> <button id='btnExport' type='button'>Export</button> </div> <script> $(document).ready(function(){ $('#btnExport').click(function(){ var link = document.createElement('a'); link.download = "myFirstExample.xls"; link.href = 'data:,' + $('#tblExport').text(); link.click(); }); }); </script> </body> </html>
[ code ]
<!DOCTYPE html> <html lang="en"> <head> <meta name="Author" content="serpiko@hanmail.net" /> <meta name="description" content="http://serpiko.tistory.com" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <!--<meta name="viewport" content="width=device-width, initial-scale=1">--> <meta name="format-detection" content="telephone=no" /> <link rel="styleesheet" type="text/css" href="" /> <link rel="shortcut icon" href="" /> <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script> <title>Document</title> <style> * { box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; } table{ width: 650px; text-align: center; border: 1px solid black; } </style> </head> <body> <div id="wrap"> <table id='tblExport'> <thead> <tr> <th>No</th> <th>Title</th> <th>Type</th> <th>Author</th> <th>URL</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>SAP : Study And Programming</td> <td>Blog</td> <td style='background-color: LightBlue;'>Serpiko</td> <td>http://serpiko.tistory.com/</td> </tr> <tr> <td>2</td> <td>Twitter</td> <td>SNS</td> <td>Obvious, LLC</td> <td>https://www.twitter.com/</td> </tr> <tr> <td>3</td> <td>Instagram</td> <td>SNS</td> <td>Kevin Systrom, Mike Krieger</td> <td>https://instagram.com/</td> </tr> </tbody> </table> <button id='btnExport' type='button'>Export</button> </div> <script> $(document).ready(function(){ function itoStr($num) { $num < 10 ? $num = '0'+$num : $num; return $num.toString(); } var btn = $('#btnExport'); var tbl = 'tblExport'; btn.click(function(e){ var dt = new Date(); var year = itoStr( dt.getFullYear() ); var month = itoStr( dt.getMonth() + 1 ); var day = itoStr( dt.getDate() ); var hour = itoStr( dt.getHours() ); var mins = itoStr( dt.getMinutes() ); var postfix = year + month + day + "_" + hour + mins; var fileName = "MyTable_"+ postfix + ".xls"; var a = document.createElement('a'); var data_type = 'data:application/vnd.ms-excel'; var table_div = document.getElementById( tbl ); var table_html = table_div.outerHTML.replace(/ /g, '%20'); a.href = data_type + ', ' + table_html; a.download = fileName; a.click(); e.preventDefault(); }); }); </script> </body> </html>
[ 직접 보기 ↓ http://www.serpiko.meximas.com/JAVASCRIPT/excel/02_dataAndAuse.html ]
[결과 화면 ]
위에 살펴보았던 것 과 다르게 테이블의 형태를 유지하며, 파일이름도 지정해 줄 수 있다.
그러나 자세히 보면 엑셀 특유의 그리드가 보이지 않는다.
3. jquery.battatech.excelexport 라이브러리를 사용하기.
1,2 의 단점을 모두 해결해 줄 jquery.battatech.excelexport 라이브러리를 소개한다.
단순히 TABLE element말고도 XML, JSON 등을 같이 지원한다.
다운로드 https://github.com/battatech/battatech_excelexport
jquery.techbytarun.excelexportjs.min.js
jquery.techbytarun.excelexportjs.js
개요 : http://battatech.com/blog/how-to-export-to-excel-sheet-on-client-side
기본사용법은 다음과 같다.
[ code ]
<!DOCTYPE html> <html lang="en"> <head> <meta name="Author" content="serpiko@hanmail.net" /> <meta name="description" content="http://serpiko.tistory.com" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <!--<meta name="viewport" content="width=device-width, initial-scale=1">--> <meta name="format-detection" content="telephone=no" /> <link rel="styleesheet" type="text/css" href="" /> <link rel="shortcut icon" href="" /> <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script> <script type="text/javascript" src="js/jquery.battatech.excelexport.js"></script> <title>Document</title> <style> * { box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; } table{ width: 650px; text-align: center; border: 1px solid black; } </style> </head> <body> <div id="wrap"> <table id='tblExport'> <thead> <tr> <th>No</th> <th>Title</th> <th>Type</th> <th>Author</th> <th>URL</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>SAP : Study And Programming</td> <td>Blog</td> <td style='background-color: LightBlue;'>Serpiko</td> <td>http://serpiko.tistory.com/</td> </tr> <tr> <td>2</td> <td>Twitter</td> <td>SNS</td> <td>Obvious, LLC</td> <td>https://www.twitter.com/</td> </tr> <tr> <td>3</td> <td>Instagram</td> <td>SNS</td> <td>Kevin Systrom, Mike Krieger</td> <td>https://instagram.com/</td> </tr> </tbody> </table> <button id='btnExport' type='button'>Export</button> </div> <script type="text/javascript"> $(document).ready(function () { $("#btnExport").click(function () { $("#tblExport").excelexportjs({ containerid: "tblExport" , datatype: 'table' }); }); }); </script> </body> </html>
15 ~ 16 : 엑셀 라이브러리를 불러오기 전에 반드시 제이쿼리 엔진이 먼저 호출되어야 한다.
33 : Table에 ID를 지정해 주고
68 : Button 에 ID를 지정해 준다.
73 : 버튼을 클릭하면 battatech_excelexport 객체에 접근하여 containerid는 테이블이름, datatype은 table로 지정해 준다.
[ 직접 보기 ↓ http://www.serpiko.meximas.com/JAVASCRIPT/excel/03_libTable.html ]
[ 결과 확인 ]
드디어 말끔하게 이상없이 다 출력된다. 그러나 파일명을 지정하지 않았기 때문에 "다운로드.xls"로 되어있다.
4. jquery.battatech.excelexport 라이브러리를 사용하여 파일이름 지정하기.
jquery.battatech.excelexport 라이브러리에서 파일명을 지정하는 방법은 다음과 같다.
<!DOCTYPE html> <html lang="en"> <head> <meta name="Author" content="serpiko@hanmail.net" /> <meta name="description" content="http://serpiko.tistory.com" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <!--<meta name="viewport" content="width=device-width, initial-scale=1">--> <meta name="format-detection" content="telephone=no" /> <link rel="styleesheet" type="text/css" href="" /> <link rel="shortcut icon" href="" /> <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script> <script type="text/javascript" src="js/jquery.battatech.excelexport.js"></script> <title>Document</title> <style> * { box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; } table{ width: 650px; text-align: center; border: 1px solid black; } </style> </head> <body> <div id="wrap"> <table id='tblExport'> <thead> <tr> <th>No</th> <th>Title</th> <th>Type</th> <th>Author</th> <th>URL</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>SAP : Study And Programming</td> <td>Blog</td> <td style='background-color: LightBlue;'>Serpiko</td> <td>http://serpiko.tistory.com/</td> </tr> <tr> <td>2</td> <td>Twitter</td> <td>SNS</td> <td>Obvious, LLC</td> <td>https://www.twitter.com/</td> </tr> <tr> <td>3</td> <td>Instagram</td> <td>SNS</td> <td>Kevin Systrom, Mike Krieger</td> <td>https://instagram.com/</td> </tr> </tbody> </table> <a id="btnExport" href="#" download="">Export</a> </div> <script type="text/javascript"> $(document).ready(function () { $("#btnExport").on('click', function () { var uri = $("#tblExport").excelexportjs({ containerid: "tblExport" , datatype: 'table' , returnUri: true }); $(this).attr('download', 'ExportToExcel.xls').attr('href', uri).attr('target', '_blank'); }); }); </script> </body> </html>
68 : 위에서 썼던 방식과 다르게 button element가 아니라 <a> element를 사용한다.
77 : battatech_excelexport객체의 멤버변수인 returnUri가 기본값이 false로 되어있는데 true로 바꾸어준다.
80 : this 는 <a> 자기자신을 의미하며 download 속성에는 'ExportToExcel.xls'을
href 속성에는 uri변수 ( jquery.battatech.excelexport 에서 처리 되고 나온 결과값 ) 이 반영된다.
target 속성은 _blank (새창)
[ 직접 확인 ↓ http://www.serpiko.meximas.com/JAVASCRIPT/excel/04_libTableReturnUri.html ]
[ 결과 확인 ]
이제 모양과 파일 이름까지 잘 반영 된다.
마지막 단계에서 우리가 할 일은 날짜와 시간을 파일명에 반영하여 최종본으로 완성해 보겠다.
5. jquery.battatech.excelexport 라이브러리를 사용하여 파일이름 지정하기2 [최종]
jquery.battatech.excelexport 라이브러리 사용에서 파일명을 지정하고 실무에서 사용하기 위한 용도의 마지막 단계 설명이다.
[ code ] demo.zip
<!DOCTYPE html> <html lang="en"> <head> <meta name="Author" content="serpiko@hanmail.net" /> <meta name="description" content="http://serpiko.tistory.com" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <!--<meta name="viewport" content="width=device-width, initial-scale=1">--> <meta name="format-detection" content="telephone=no" /> <link rel="styleesheet" type="text/css" href="" /> <link rel="shortcut icon" href="" /> <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script> <script type="text/javascript" src="js/jquery.battatech.excelexport.js"></script> <title>Document</title> <style> * { box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; } table{ width: 650px; text-align: center; border: 1px solid black; } </style> </head> <body> <div id="wrap"> <table id='tblExport'> <thead> <tr> <th>No</th> <th>Title</th> <th>Type</th> <th>Author</th> <th>URL</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>SAP : Study And Programming</td> <td>Blog</td> <td style='background-color: LightBlue;'>Serpiko</td> <td>http://serpiko.tistory.com/</td> </tr> <tr> <td>2</td> <td>Twitter</td> <td>SNS</td> <td>Obvious, LLC</td> <td>https://www.twitter.com/</td> </tr> <tr> <td>3</td> <td>Instagram</td> <td>SNS</td> <td>Kevin Systrom, Mike Krieger</td> <td>https://instagram.com/</td> </tr> </tbody> </table> <a id="btnExport" href="#" download=""> <button type='button'>Export</button> </a> </div> <script type="text/javascript"> $(document).ready(function () { function itoStr($num) { $num < 10 ? $num = '0'+$num : $num; return $num.toString(); } var btn = $('#btnExport'); var tbl = 'tblExport'; btn.on('click', function () { var dt = new Date(); var year = itoStr( dt.getFullYear() ); var month = itoStr( dt.getMonth() + 1 ); var day = itoStr( dt.getDate() ); var hour = itoStr( dt.getHours() ); var mins = itoStr( dt.getMinutes() ); var postfix = year + month + day + "_" + hour + mins; var fileName = "MyTable_"+ postfix + ".xls"; var uri = $("#"+tbl).excelexportjs({ containerid: tbl , datatype: 'table' , returnUri: true }); $(this).attr('download', fileName).attr('href', uri).attr('target', '_blank'); }); }); </script> </body> </html>
[ 직접 확인 ↓ http://www.serpiko.meximas.com/JAVASCRIPT/excel/05_libTableReturnUri_2.html ]
[ 결과 확인 ]
1 ~ 5 단계를 통하여 Table에 대한 xls 저장과, 라이브러리를 통한 xls 내보내기에 대하여 살펴 보았다.
의문점
jquery.battatech.excelexport.js 의 엔진을 살펴보면 마지막 return 스트링에 아래와 같은 내용이 있다.
1. <head> ~ </head> 사이에 META 태그로 파일명을 넣을 수 있게 하면 편했을 텐데 왜 지원하지 않았을까?
META 태그에서는 <meta name="content-disposition" content="inline; filename=myExcel.xls"> 과 같이 파일명을 지정해 줄 수 있다.
실제로 서버사이드에서 Excel Export 를 할 경우 자주 쓰였던 방법이다.
해본 결과 일단 META 태그로는 파일명이 바뀌지 않는다.
2. 그렇다면 data:application/octet-stream;base64,SGVsbG8= 의 URI 속성에 파일명을 지정해 줄 수는 없을까?
역시 NO.
일단 data URI의 목적은 데이터 스트림이지 파일이 아니라는 점과 애초에 소스파일로서 취급되어 에이전트에서 핸들링 되지
않는다는 것이다.
( The entire purpose is that it's a datastream, not a file.
The data source should not have any knowledge of the user agent handling it as a file... and it doesn't.
http://stackoverflow.com/questions/283956/is-there-any-way-to-specify-a-suggested-filename-when-using-data-uri )
3. 원인과 결과
HTML5는 <A> element의 "download" 속성을 발표했다. 보편적은(구형IE브라우저를 지원하지 못하지만) 아니지만 사용자가
하이퍼 링크를 클릭 할 때 대상을 다운로드 하도록 지정하는 공식적인 기능이다.
( Specifies that the target will be downloaded when a user clicks on the hyperlink. )
따라서 1~2번의 만들어진 DIV를 <A> element 통해 트리거한 이유가 여기에 있다.
2번 항목 참조 : http://www.kubilayerdogan.net/javascript-export-html-table-to-excel-with-custom-file-name/
'■ 프론트엔드 ■ > JavaScript' 카테고리의 다른 글
Object.length 메서드 확장하여 사용하기 (0) | 2016.07.29 |
---|---|
selectbox와 쿠키 사용하기 (1) | 2016.03.23 |
정규식 (1) | 2015.02.05 |
변수에 함수를 할당 (0) | 2014.05.09 |
window.open() 메서드 : 새 브라우저 창을 엽니다. (0) | 2014.05.07 |