웹에서 png저장 없이 엑셀에 이미지 출력 - 클라이언트

lsj8367·2021년 4월 19일
0

앞전에서는 Java에서 웹에서 png소스를 받아서 엑셀에 이미지를 업로드 하는 것을 포스팅했다.
이번에는 png소스를 Java로 넘겨주는 스크립트를 구현하였다.
코드를 보면서 설명을 하겠다.

HTML

index.html

<!DOCTYPE html>
<html lang="ko">
    <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
    <script src="https://code.highcharts.com/highcharts.js"></script>
    <script src="https://code.highcharts.com/modules/annotations.js"></script>
    <script src="https://code.highcharts.com/modules/exporting.js"></script>
    <meta charset="UTF-8">
    <title>하이차트 예제</title>
</head>

<body style="background-color: lightgray;">
    <div id="container" style="width:1200px; height:400px;"></div>
    <button onclick="draw()">
        엑셀로 저장하기
    </button>

  	<!-- 캔버스 이미지 그려질 곳-->
    <canvas id="canvas" width="1200" height="400" style="display: none"></canvas>
</body>
    <script src="chart.js"></script>
</html>

highchart를 그리기 위한 cdn들을 위에 먼저 불러오고 난 후에 기본적으로 차트가 들어갈 div태그 1개와 그리고 엑셀로 저장하는 버튼, 그리고 display를 none으로 감추고 이미지는 웹상에서 보이지 않게 하는 canvas 하나를 생성하고 그 아래에 chart.js 스크립트를 불러온다.

JavaScript

chart.js

let test1; // point 첫번째
let test2; // point 두번째
let count1 = 0;
let cnt = 0;

const options = {
    chart: {
        type: 'scatter', //차트의 유형
        renderTo: 'container', //그릴 div태그의 id값
    },
    credits: { //highcharts.com 지우기
        enabled: false
    },

    title:{
        text: '제목',
    },

    subtitle: {
        text: '부제목',
    },

    xAxis : {
        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun','Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
     },

    yAxis: [
    { //--- Primary yAxis
        title: {
            text: 'Temperature'
        },
        labels: {
            format: '{value} %',
        },

    },

    ],
    
    series: [ //차트에 들어가는 값
        {
            keys: ['y', 'id'], //키 id값 설정해줌.
            data: [
                [29.9, '0'], [71.5, '1'], [106.4, '2'], [129.2, '3'],
                [29.9, '4'], [71.5, '5'], [106.4, '6'], [129.2, '7'],
                [29.9, '8'], [71.5, '9'], [106.4, '10'], [129.2, '11'],
                [29.9, '12'], [71.5, '13'],
            ],

            
        },
            
        ],

   annotations: [{
		labels: [
          {
			point: '0', //0번째 점
			x: 50, //선 길이 왼쪽오른쪽 조절
			y: 200, // 위아래 선길이
			format: '비가 많이왔음',
		  }
        ],
	}],

}

const chart = new Highcharts.Chart(options);

//이미지 만들기
function draw(){
    
    const createSvg = chart.getSVG({ //svg 태그 만들기
        chart:{
            width: 1200,
            height: 400,
        }
    })
	//console.log(createSvg); //이 부분을 출력하면 <svg>태그가 생성되는 것을 확인 가능함.
    
    const canvas = document.getElementById("canvas"); //canvas 아이디값
    const ctx = canvas.getContext("2d");
    const DOMURL = self.URL || self.webkitURL || self;
    const img = new Image();
    const svg = new Blob([createSvg], {type: "image/svg+xml;charset=utf-8"}); //svg를 base64형식으로 바꾼다.
    const url = DOMURL.createObjectURL(svg);

    img.onload = function() {
        ctx.drawImage(img, 0, 0); //캔버스 차트를 그림
        const png = canvas.toDataURL("image/png"); //canvas png로 바꾸기
        //console.log(png); // data:image/png;base64,iVBORw .... 나옴
      
        $.ajax({
              type: 'post',
              url: 'excelGo',
              data: png,
              contentType: "application/json",
              success: function(data) {
                  // 픽셀 정리
                  ctx.clearRect(0, 0, canvas.width, canvas.height);
                  // 컨텍스트 리셋
                  ctx.beginPath();
              }
          })
    };
    img.src = url;
}

위의 코드 진행 방식은 차트에 대한 옵션들은 이 포스팅에서 다루지 않으니 주석으로 설명을 대체하겠다. 그렇게 생성한 옵션들을 통해 const chart 를 통해 Highchart를 그린다.
여기까지는 일단 html을 실행했을때 나오게되는 기본적인 차트이다.
이미지는 아래와 같다.

이 상태에서 아래 보이는 차트그리기 버튼을 클릭하게 되면 chart.js의 draw()함수를 호출한다.
chart.getSVG()라는 기본 제공해주는 함수를 통해 svg태그를 생성받는다. 구글로 검색을 해봤을때 svg, png, jpeg 등 기본 값으로 설정해줄 수가 있다는데 나는 아직 찾지 못해서
svg를 canvas에 그린 후 다시 png로 추출하는 작업을 진행하였다.

그 다음 Ajax호출로 base64의 png값을 Java단으로 전송한다. 그렇게 해서 이전 포스팅의 xlsWriter 메소드로 가서 엑셀에 저장하는 것을 진행하게 된다.

그 이후에 canvas의 display: none;속성으로 인해 웹상에서는 보이지 않지만 그림은 버튼 밑으로 그려져 있지만 공간은 가지고 있지 않기 때문에 성공했을 시
즉, success: function() 에서 ctx로 그렸던 차트를 픽셀과 context를 리셋시켜주는 동작을 실행시켜주고 마무리 한다.

정상적으로 실행이 됐을때 엑셀에서는 이런 모습이 나오게 된다.

마무리

검색해도 나오지 않는 것을 구현했을 때 더더욱 내 블로그에 글을 많이 써서 이전에 기록을 했었는데 기억나지 않는게 생긴다면 내 블로그에 다시 돌아와서 보는 것들이 많았으면 좋겠다.

profile
기록을 많이 하자!💻

0개의 댓글