React React-to-Print

배추·2025년 7월 4일
0

React React-to-Print에 대해 알아봅니다.


참고) https://www.npmjs.com/package/react-to-print

▶React-to-Print 적용

패키지 설치

npm install react-to-print

작동 방식

  • 출력할 컴포넌트를 ref로 지정.
  • useReactToPrint() 훅을 통해 프린트 기능을 연결.

예시

import { useRef } from "react";
import { useReactToPrint } from "react-to-print";

// 출력할 컴포넌트
const PrintView = () => {
  // 출력 대상 요소를 가리킬 ref
  const contentRef = useRef<HTMLDivElement>(null); 
  
  // 프린트 기능 hook
  const reactToPrintFn = useReactToPrint({
    contentRef, // ref로 가리킨 요소를 출력
    documentTitle: "견적서", // 문서 제목
  });

  return (
    <div> 
      <MiniBtn
        text="견적서 출력하기"           
        onClick={reactToPrintFn}
      />
      
      {/* 출력 대상 영역 */}
      <div ref={contentRef}>
        <QuotationDocumentView />
      </div>
    </div>
  );
};

export default PrintView;

▶프린트 전용 CSS

: 프린트 전용 css를 따로 만들 수 있다!

방법1) inline

  • Tailwind에서는 print: 접두사를 사용해 프린트 전용 스타일 적용 가능.
<div ref={contentRef} className="print:p-8">
  <QuotationDocumentView />
</div>

방법2) 전역 설정

  • 출력된 뷰의 여백 설정.
  • placeholder 숨기기.
  • 페이지 나눔 설정: 요소가 프린트 시 중간에서 잘리는 것을 방지.
/* global.css */

/* 프린트 시 문서 스타일 설정 */
@media print {
  /* 폰트 */
  * {
    font-family:
      "Pretendard"
  }

  /* placeholder 숨기기 */
  ::placeholder {
    color: transparent !important;
  }
  ::-webkit-input-placeholder {
    color: transparent !important;
  }
  :-ms-input-placeholder {
    color: transparent !important;
  }
  ::-ms-input-placeholder {
    color: transparent !important;
  }

  /* 페이지 나눔 설정 */
  p {
    page-break-inside: avoid; /* 요소 내부에서 페이지 나눔 방지 */
    break-inside: avoid;
  }

  tr {
    page-break-inside: avoid; /* 테이블 행이 잘리지 않도록 */
    break-inside: avoid;
  }

  /* 페이지 여백 설정 */
  @page {
    margin: 32px;
  }
}

▶textarea는...

❗문제점

  • <textarea>는 프린트 시 스크롤 박스로만 렌더링된다.
  • 내용이 길어져도 높이가 자동으로 늘어나지 않아 내용이 잘려서 출력.
  • height: auto도 프린트에서는 적용되지 않는다.

=> 높이가 내용에 맞게 자동으로 늘어나지 않음!!! textarea의 실제 내용을 모두 출력할 수 없음!!!

💡해결책

프린트할 때 <textarea>를 일반 텍스트 블록(div, pre 등)으로 교체해서 출력

<div className="flex flex-col gap-3">
  <h3 className="Heading-3">메모</h3>

  {/* 입력용 textarea - 화면에서만 표시 */}
  <textarea
    placeholder="메모를 입력하세요."
    value={value}
    onChange={(e) => setValue(e.target.value)}
    className="w-full min-h-50 print:hidden"
  />

  {/* 프린트용 div - 프린트에서만 표시 */}
  <div className="textarea hidden print:block whitespace-pre-wrap w-full min-h-50">
    {value}
  </div>
</div>
  • 일반 화면에서는 <textarea>를 보여주고,
  • 프린트할 때는 <div> 형태로 바뀌어서 글자 수만큼 자동으로 줄이 늘어나도록 설정.
    • 출력용 <div>에도 textarea의 스타일이 들어갈 수 있도록 하기~
    • whitespace-pre-wrap: 줄바꿈 및 공백 유지.
profile
난 🥬

0개의 댓글