본문 바로가기
Javascript

웹에서 svg를 excel에 저장하는 방법

by 하이바네 2022. 5. 26.
반응형

svg를 excel로 출력하기 위해서는 몇가지 작업이 필요하다.

 

일반적인 자바스크립트 excel 라이브러리에서는 base64로 인코딩된 이미지를 넣을 수 있게 지원 해준다.

 

https://github.com/exceljs/exceljs

 

GitHub - exceljs/exceljs: Excel Workbook Manager

Excel Workbook Manager. Contribute to exceljs/exceljs development by creating an account on GitHub.

github.com

일반적으로 사용하는 exceljs 라이브러리 이다.

 

그리고 프론트에서 파일 저장을 서버를 거치지 않고 사용하는 라이브러리인 fileSaverjs

https://github.com/eligrey/FileSaver.js/

 

GitHub - eligrey/FileSaver.js: An HTML5 saveAs() FileSaver implementation

An HTML5 saveAs() FileSaver implementation. Contribute to eligrey/FileSaver.js development by creating an account on GitHub.

github.com

위의 두 라이브러리 조합이면 프론트엔드에서 엑셀로 파일 출력이 가능하다.

 

 

위의 코드들을 이용한 샘플 코드

        encodedData = canvas.toDataURL("image/png");//이 부분은 별도의 작업이 추가로 필요
 
        //엑셀 시트
        let workbook = new ExcelJS.Workbook();
        let worksheet = workbook.addWorksheet('sheet');

        //이미지 등록
        let imageId = workbook.addImage({
          base64: encodedData,
          extension: 'jpeg'
        });
      
        worksheet.addImage(imageId, {
          tl: { col: 0, row: 0 },
          ext: { width: canvas.width, height: canvas.height }
        });

        //엑셀 row의 높이 가져오고 첫번째 행 높이 변경
        worksheet.getRow(1).height = canvas.height;
        
		//엑셀에 문자열 데이터 입력        
        let rowValues = [
          'sample data1',
          'sample data2',
          'sample data3',
          'sample data4',
          'sample data5',
          'sample data6',
          'sample data7',
          new Date()
        ];

        worksheet.addRow(rowValues);

        workbook.xlsx.writeBuffer().then(function(data){
          let blob = new Blob([data], {type: "application/vnd.ms-excel;charset=utf-8"});
          var saveTime = new Date(+new Date() + 3240 * 10000).toISOString().replace("T", "_").replace(/\..*/, '').replaceAll(":",".");//파일명 날짜 설정
          saveAs(blob,saveTime+".xlsx");
        });

위의 코드에서 encodedData를 사용하는 부분만 제외하면 엑셀 출력이 될 것이다.

 

그럼 svg를 저장하는 방법은 아래와 같다

 

1. svg를 image 태그에 출력

2. img태그를 canvas에 출력

3. canvas에서 base64로 이미지 형태로 내보내기

 

위의 내용을 조금 더 코드와 함께 정리해서 보자면 아래와 같다.

 

1. document.createElement를 이용해서 img 태그, canvas 태그를 생성하고

2. img태그에 svg를 출력

      //get svg
      var $svg = document.querySelector("svg");

      //image element
      var img = document.createElement('img');
      
      //canvas element(실제 canvas의 사이즈가 excel에 삽입됨)
      canvas = document.createElement('canvas');
      canvas.width = 1024;
      canvas.height = 350;
      
      ctx = canvas.getContext('2d');
      var xml = new XMLSerializer().serializeToString($svg);
      console.log('height',document.querySelector("svg").style.height);
      console.log('width',document.querySelector("svg").style.width);
      
      var svg64 = window.btoa(xml);
      
      var b64Start = 'data:image/svg+xml;base64,';

      var image64 = b64Start + svg64;
      img.src = image64;

img태그에 이미지가 들어가는것은 비동기이므로 이벤트 리스너 생성 및 나머지 수행

img.addEventListener('load', e => {

  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);//캔버스에 이미지 그리기
  encodedData = canvas.toDataURL("image/png");//캔버스에 그려진 이미지의 base64 가져오기
    
  //나머지 엑셀에 출력 관련 수행
});

 

이런방식으로 base64로 인코딩된 이미지를 가져와서 수행하면 된다.

 

여기에서 생략된 것은 canvas의 사이즈를 하드코딩으로 넣어놓은 것이다. 특정 태그의 사이즈를 넣는것도 좋고 단 주의할점은 display:none인 태그는 사이즈가 잡히지 않는다는 것이다.(이걸로 삽질을 좀 했음...)

 

728x90

댓글