1. 목표
- 특정 HTML을 이미지로 다운로드 하기
- HIghcharts를 이미지로 다운로드 하기
- 생성한 이미지를 PDF로 다운로드 하기
2. 사용 라이브러리
- html2canvas.js
- canvg.js
- highcharts.js
3. 이슈 정리
- IE에서 html2canvas로 HTML을 이미지로 만들때 오류 발생
* es6-promise.auto.js 추가로 해결
- IE에서 차트 이미지가 생성되지 않는 문제 발생
* svg tag를 인식 하지 않는 것 같음.
구글링 ..
구글링 .. ..
4. 이슈 해결
- 해결이라기 보다 원하는 기능을 구현하고자 우회..
- 다운로드시 highchart export 기능을 이용하여 이미지로 생성한 후 각 차트 svg 위치에 대체
ex) 이미지가 svg 위치로 들어가고 svg는 잠시 hidden. 다운로드가 완료되면 다시 원복
5. 소스 코드
- 사용한 JS 첨부
<script src="./js/jquery-1.11.3.min.js"></script>
<!-- highcharts -->
<script src="./js/highcharts.js"></script>
<script src="./js/exporting.js"></script>
<script src="./js/export-data.js"></script>
<!-- html2canvas (html to image) -->
<script src="./js/html2canvas.js"></script>
<script src="./js/es6-promise.auto.js"></script>
<!-- canvg (svg to image) -->
<script src="./js/rgbcolor.min.js"></script>
<script src="./js/stackblur.min.js"></script>
<script src="./js/canvg.min.js"></script>
<!-- PDF -->
<script src="./js/html2pdf.js"></script>
<script src="./js/jspdf.debug.js"></script>
- hicharts 샘플
$(document).ready(function () {
drawHighcharts();
});
function drawHighcharts() {
Highcharts.chart('container', {
exporting: { enabled: false},
title: {text: 'Solar Employment Growth by Sector, 2010-2016111'},
subtitle: {text: 'Source: thesolarfoundation.com'},
yAxis: {title: {text: 'Number of Employees'}},
legend: {layout: 'vertical', align: 'right', verticalAlign: 'middle'},
plotOptions: {series: {label: {connectorAllowed: false}, pointStart: 2010}},
series: [{name: 'Installation',
data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
}, {
name: 'Manufacturing',
data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434]
}, {
name: 'Sales & Distribution',
data: [11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387]
}, {
name: 'Project Development',
data: [null, null, 7988, 12169, 15112, 22452, 34400, 34227]
}, {
name: 'Other',
data: [12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111]
}],
responsive: {
rules: [{
condition: {
maxWidth: 1000
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
});
Highcharts.chart('container2', {
exporting: {enabled: false},
title: {text: 'Client-Side Download Example'},
subtitle: {text: 'Click "Save Chart" to download chart as PNG'},
chart: {type: 'area'},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
});
}
- script
<!-- java로 이미지 다운로드 -->
function downloadImage() {
createChartImages();
setTimeout(function () {
downloadImageServer();
}, 1000);
}
<!-- script로 이미지 다운로드 -->
function downloadImage2() {
createChartImages();
setTimeout(function () {
downloadImageWeb();
}, 1000);
}
function downloadPDF() {
createChartImages();
setTimeout(function () {
createPDF();
}, 1000);
}
<!-- 특정 위치에 있는 svg를 찾아서 이미지화 한다 -->
function createChartImages() {
$('svg').each(function () {
var chartId = $(this).parents().parents().attr('id');
var chart = $('#' + chartId).highcharts();
var render_width = $(this).width;
var render_height = render_width * chart.chartHeight / chart.chartWidth;
// exporting.js
var svg = chart.getSVG({
exporting: {
sourceWidth: chart.chartWidth,
sourceHeight: chart.chartHeight
}
});
var tempCanvas = document.createElement('canvas');
tempCanvas.height = render_height;
tempCanvas.width = render_width;
canvg(tempCanvas, svg);
var imgData = tempCanvas.toDataURL('image/png');
var imgTag = '<img src="' + imgData + '">';
$('#' + chartId).find('div:first').append(imgTag);
$(this).hide();
});
}
function downloadImageServer() {
html2canvas(document.querySelector('#contents')).then(function(canvas) {
$('#data').val(canvas.toDataURL("image/png"));
$('#imageForm').submit();
});
showCharts();
}
function downloadImageWeb() {
html2canvas(document.querySelector('#contents')).then(function(canvas) {
var imgSrc = canvas.toDataURL();
var fileName = 'sample_web.png';
var imgData = atob(imgSrc.split(",")[1]),
len = imgData.length,
buf = new ArrayBuffer(len),
view = new Uint8Array(buf),
blob,
i;
for (i = 0; i < len; i++) {
view[i] = imgData.charCodeAt(i) & 0xff // masking
}
blob = new Blob([view], {
type: "application/octet-stream"
});
// ie
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName)
} else {
var a = document.createElement("a");
a.href = imgSrc;
a.download = fileName;
document.body.appendChild(a)
a.click();
setTimeout(function() {
document.body.removeChild(a)
}, 100)
}
});
showCharts();
}
function createPDF() {
html2canvas(document.querySelector('#contents')).then(function(canvas) {
var pdf = new jsPDF('1', 'pt', 'a4');
pdf.text(34, 23, '2018-12-03');
var chartImgData = canvas.toDataURL("image/png");
pdf.addImage(chartImgData, 'png', 30, 60, 500, 600);
pdf.save('create.pdf');
});
showCharts();
}
function showCharts() {
setTimeout(function () {
$('svg').each(function () {
$(this).show();
$(this).next('img').remove();
});
}, 2000);
}
- style
<style>
#contents {width: 605px;}
#container, #container2 {width: 600px;height: 400px;}
</style>
- HTML : #container, #container2 안에 highchart를 만들고 #contents를 이미지로 변환한다.
<div>
<form id="imageForm" method="post" action="/download/image">
<input type="hidden" id="data" name="data" value="">
</form>
<button onclick="downloadImage();">download image</button>
<button onclick="downloadImage2();">download image2</button>
</div>
<div id="contents">
<div id="container"></div>
<div id="container2"></div>
</div>
6. 참조 사이트
- http://codingdojang.com/scode/356
- http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/members/chart-getsvg/
- https://stackoverflow.com/questions/46366054/html2canvas-of-a-highcharts-chart-not-working-fine-on-ie
- https://www.npmjs.com/package/canvg
* 너무 많은 구글링으로 인해 참조한 사이트의 정보가 누락된 것도 있으니 양해 바랍니다.
7. 마무리
위 소스는 크롬에서 동작이 잘 되며, IE9+ 이상 동작하는것을 확인하였음.
다만, IE에서 PDF로 다운로드시 PDF가 정상적으로 열리지 않을 때가 있고, 첨부한 이미지이 화질이 좋지 않아 개선할 필요가 있음.
'개발' 카테고리의 다른 글
[Apache] JMeter 사용기 (0) | 2020.02.11 |
---|---|
[GIT] 자주 사용하는 GIT 명령어 정리 (0) | 2020.02.11 |
[MySQL] 데이터베이스, 테이블, 유저 생성 및 권한 부여 (0) | 2017.12.20 |
아마존웹서비스(AWS EC2) Ubuntu 16.04 서버에 MySQL 5.7 설치하기 (0) | 2017.12.20 |
WAS 구동 없이 컨트롤러 테스트 (0) | 2017.12.19 |