반응형
snowman95
코딩수련장
snowman95
전체 방문자
오늘
어제
  • 분류 전체보기 (229)
    • 앱테크 (3)
    • 옵시디언 (5)
    • 드라마, 영화 (1)
    • 개발자 이야기 (23)
    • 프로젝트 (10)
      • 프로젝트 방법론 (7)
      • 프로젝트 기록 (2)
      • Github (1)
    • 개발 지식 (0)
      • 디자인 패턴 (0)
    • 프론트엔드 개발 (5)
      • 테크트리 (2)
      • React.js (19)
      • ReactNative (2)
      • Next.js (6)
      • GraphQL (6)
      • 패키지 매니저 (2)
      • 라이브러리 (3)
      • 상태관리 라이브러리 (4)
      • Web 지식 (3)
      • HTML CSS (26)
      • Javascript (16)
      • 도구 (Tool) (3)
      • 성능 최적화 (1)
      • 디자인시스템 (0)
    • Python (53)
      • 모음집 (1)
      • 문법 (12)
      • 라이브러리 (15)
      • 알고리즘 (10)
      • 백준 문제풀이 (9)
      • 코딩테스트 (2)
      • 도구 (Tool) (3)
    • C++ (20)
      • 알고리즘 (6)
      • 삼성SW기출 (6)
      • 삼성 A형 (6)
    • 데이터사이언스 (1)
    • 인프라 (9)
      • 하드웨어 지식 (4)
      • Ansible (2)
      • Database (2)
      • 쉘스크립트 (1)
    • 주식 (0)
    • 취업 준비 (4)
      • 취업 이야기 (0)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • 삼성SDS
  • 삼성SW역량테스트
  • 전공 요약 #운영체제
  • A형
  • 티스토리챌린지
  • 오블완
  • 전공요약
  • nextjs
  • 전공 요약 #네트워크
  • C++
  • GraphQL
  • 면접
  • 백준
  • 나의 해방일지
  • Next.js #graphql #tailwind.css
  • 언어
  • 전공 요약 #데이터베이스
  • 공간복잡도
  • 기계식키보드 #nuphy
  • 알고리즘

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
snowman95

코딩수련장

리액트 컴포넌트를 pdf 파일로 저장하기 (html2canvas, jspdf)
프론트엔드 개발/React.js

리액트 컴포넌트를 pdf 파일로 저장하기 (html2canvas, jspdf)

2023. 7. 12. 17:47
728x90
반응형

react-pdf 라이브러리를 사용해서 전용컴포넌트로 한땀한땀 쌓아올려서 pdf 파일을 만들어도 되지만 그건 너무나 귀찮습니다.

저희는 웹페이지의 화면을 캡쳐해서 pdf 파일로 다운로드 받는 편한 방법을 사용할 것입니다.

 

아래의 두 패키지를 설치합니다.

yarn add html2canvas jspdf

html2canvas 는 리액트 컴포넌트를 이미지로 변환해주는 라이브러리고

jspdf는 그 이미지를 pdf파일로 만들어주는 라이브러리 입니다.

 

 

이슈들

그런데 사용해보면 바로 이슈가 터져 나옵니다. 이슈 해결하면서 해결된 코드도 같이 보겠습니다.

이슈1 : 페이지 높이가 너무 높아서 (내용이 너무 길어서) pdf 파일안에 다 담기지 않고 잘리는 이슈

처음에 인터넷에서 흔한 코드 긁어와서 pdf파일의 width, height 를 설정해주었습니다.

잘 된 줄알고 기뻐하고 있는데 페이지 하단을 보니 내용이 잘려있습니다. 그래서 높이 부분을 무작정 건드렸더니 해상도가 깨집니다.

 

이것은 페이지 높이가 너무 길어서 발생하는 이슈였으며,

아래와 같이 코드 수정해주었더니 페이지 잘리지 않고 전체 페이지 내용이 잘 보여집니다.

 

import { useEffect, useRef, useState } from 'react'
import html2canvas from 'html2canvas'
import { jsPDF } from 'jspdf'

const 컴포넌트 = ()=>{
  const printRef = useRef<HTMLElement>(null)

  const handleDownloadPdf = async () => {
    const element = printRef.current
    if (!element) {
      return
    }
    const canvas = await html2canvas(element)
    const componentWidth = element.offsetWidth
    const componentHeight = element.offsetHeight

    const orientation = componentWidth >= componentHeight ? 'l' : 'p'

    const imgData = canvas.toDataURL('image/png')
    const pdf = new jsPDF({
      orientation,
      unit: 'px',
    })

    pdf.internal.pageSize.width = componentWidth
    pdf.internal.pageSize.height = componentHeight

    pdf.addImage(imgData, 'PNG', 0, 0, componentWidth, componentHeight)
    pdf.save('대출제안서.pdf')
  }
  
   return (
     <>
       <section className="flex flex-col gap-20 py-20 px-30 bg-piper-grey-100" 
         ref={printRef}>
         // 컴포넌트 내용...
       </section>
       <button onClick={handleDownloadPdf}>
         <span>PDF 다운로드</span>
       </button>       
     </>
   )
 }

 

이슈2 : 일부 글자가 바닥에 붙어버리는 이슈

보통 div 박스 안에 글자를 중앙에 정렬한 경우 공통적으로 발생했습니다. (아래 이미지 참고)

무슨 수를 써도 해결되지 않았는데 원인은 정말 뜬금없이 Tailwind.css 에 있었습니다.

이것이 마법입니다.

img 의 기본 스타일에 inline-block을 추가해주어야 했습니다. 아무래도 기본 스타일이 날라가버리면서 문제가 터졌던 것 같습니다.

/* global.css */
@tailwind base;
@layer base {
  img {
    @apply inline-block;
  }
}
@tailwind components;
@tailwind utilities;

 

 

참고

- https://stackoverflow.com/a/64761137

- https://github.com/niklasvh/html2canvas/issues/2775#issuecomment-1204988157

반응형
저작자표시 비영리 동일조건 (새창열림)

'프론트엔드 개발 > React.js' 카테고리의 다른 글

리액트 렌더링 최적화를 위한 useDeferredValue 는 debounce 의 완전한 대체제가 아니다.  (0) 2023.12.29
React Query 캐시 초기화 후 다시 받아오기  (0) 2023.06.14
서버사이드 렌더링를 사용하더라도 결국 다운받는 HTML 파일 크기를 줄여야 사용자에게도 구글봇에게도 유리하다.  (0) 2023.02.05
Jotai 와 Zustand 는 무엇이 다른가요?  (0) 2023.02.05
웹 프론트엔드 유용한 링크 모음  (0) 2023.02.04
    '프론트엔드 개발/React.js' 카테고리의 다른 글
    • 리액트 렌더링 최적화를 위한 useDeferredValue 는 debounce 의 완전한 대체제가 아니다.
    • React Query 캐시 초기화 후 다시 받아오기
    • 서버사이드 렌더링를 사용하더라도 결국 다운받는 HTML 파일 크기를 줄여야 사용자에게도 구글봇에게도 유리하다.
    • Jotai 와 Zustand 는 무엇이 다른가요?
    snowman95
    snowman95
    (17~19) Unity/Unreal Engine 게임 프로그래머 (20~21) System Administrator ___________ (22~) React 웹 프론트앤드 개발자 __________ 깃헙 : https://github.com/snowman95

    티스토리툴바