개발공작소
article thumbnail
728x90
반응형

 

 

 

 

작업 전.. html2canvas 및 jspdf 라이브러리에 대한 설명..

 

우선 2개의 라이브러리를 대충 설명하면

 

html2canvas : DOM을 기반으로 하여 전체 또는 특정 영역의 스크린샷을 생성하는 라이브러리

jsPDF : javascript로 PDF를 생성해주는 라이브러리

 

대충 위와 같은 기능을 제공하는 라이브러리인 것만 인지하고 아래 그림을 보도록 하자.

 

대충 그림..

 

우리가 작성한 HTML을 PDF로 변환하는 과정은 위와 같다.

보통 인쇄 기능을 구현하거나, PDF로 변환할 때 사용자가 원하는 엘리먼트를 잡고
body를 변경해주거나, 직접 파라메터로 HTML 엘리먼트를 넣어주는데

 

여기서는 HTML 엘리먼트를 우선 이미지로 변환한 뒤, PDF로 변환해준다. ( 물론 인쇄도 된다. )

 

대충 이해 했으면 이제 설치 및 샘플코드를 보도록 하자.

 

 

html2canvas 및 jspdf 설치

 

npm 설치 명령어와 cdn링크를 달아놨으니, 각자 개발환경에 맞는 걸 갖다 쓰도록 하자.

 

 

html2canvas 설치 npm  명령어

npm i html2canvas

 

html2canvas CDN 링크

https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js

 

 

 

jspdf 설치 npm 명령어

npm i jspdf

 

jspdf CDN 링크

https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js

 

 

 

샘플코드

 

<template>
    <div id="modalSheet" class="modal modal-sheet position-static d-block bg-secondary py-5" tabindex="-1"
        role="dialog">
        <div class="modal-dialog" role="document">
            <div id="print-content" class="modal-content rounded-6 shadow">
                <div class="modal-header border-bottom-0">
                    <h5 class="modal-title"><input :value="msg" /></h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body py-0">
                    <p>This is a modal sheet, a variation of the modal that docs itself to the bottom of the viewport
                        like the
                        newer share sheets in iOS.</p>
                </div>
                <div class="modal-footer flex-column border-top-0">
                    <button type="button" class="btn btn-lg btn-primary w-100 mx-0 mb-2" @click="showPrint()">인쇄
                        미리보기</button>
                    <button type="button" class="btn btn-lg btn-light w-100 mx-0" data-bs-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>
</template>
  
<script>

import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap'
import html2canvas from 'html2canvas'
import { jsPDF } from 'jspdf'

export default {
    name: 'PrintComponent',
    props: {
        msg: String
    },
    methods: {
        showPrint() {


            html2canvas(document.querySelector('#print-content'), {
                //allowTaint: true,	// cross-origin allow
                //useCORS: true,		// CORS 사용한 서버로부터 이미지 로드할 것인지 여부
                scale: 10			// 기본 96dpi에서 해상도를 두 배로 증가

            }).then(function (canvas) {
                // 캔버스를 이미지로 변환
                let imgData = canvas.toDataURL('image/png')
                let imgWidth = 120 // 이미지 가로 길이(mm)
                let pageHeight = imgWidth * 1.414  // 출력 페이지 세로 길이
                let imgHeight = canvas.height * imgWidth / canvas.width
                let heightLeft = imgHeight
                let margin = 45 // 출력 페이지 여백설정
                let doc = new jsPDF('p', 'mm')
                let position = 10

                window.scrollTo(0, 0)

                //첫 페이지 출력
                doc.addImage(imgData, 'PNG', margin, position, imgWidth, imgHeight)
                heightLeft -= pageHeight

                //한 페이지 이상일 경우 루프 돌면서 출력
                while (heightLeft >= 20) {
                    position = heightLeft - imgHeight
                    position = position - 20
                    doc.addPage()
                    doc.addImage(imgData, 'PNG', margin, position, imgWidth, imgHeight)
                    heightLeft -= pageHeight
                }

                // PDF를 새탭으로 열기
                window.open(doc.output('bloburl'))

                // PDF를 바로 다운로드
                // doc.save('sample.pdf');

            })

        },
    }

}
</script>

 

 

결과화면

 

HTML 화면

 

PDF 새탭 화면

 

실제 위 코드로 구현한 화면이다. (나는 Vue를 기반으로 했다.. 필요한 사람들은

showPrint함수만 따로 빼서 javascript에 함수를 만들어 사용하도록 하자..

 

위 화면에서 "인쇄 미리보기" 버튼을 클릭 할 경우 새탭이 열리며 PDF 미리보기가 된다.

다운로드 및 인쇄 가능..

 

만약 미리보기가 필요 없고, 바로 PDF파일을 다운로드 받고 싶다면 

doc.svae() 부분을 주석해제 하여 사용하면 된다. 끝

 

 

 

 

 

728x90
반응형
profile

개발공작소

@모찌바라기

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!