티스토리 뷰
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 |