본문 바로가기
프론트엔드/Vue

Vue3 프린트 기능을 이용해보자!

안녕하십니까!

야생에서 등장한 하프 입니다 😊

 

이번에는 Vue3 로 프린트 기능을 사용하는 법을 알아보도록 하겠습니다 ~


해당 기능은 vue3 를 기준으로 작성되었습니다

 

 

 

📝 목차

 

 


초기 디자인

1. 폴더 구조

폴더 구조는 간단하게 설정했습니다.

2. html, css 구성

초기 디자인 구성을 위해 디자인을 해주도록 합시다!

아래의 코드는 예시 코드이며, 원하시는걸로 제작 후 사용하셔도 됩니다 !

// src/components/printFunc.vue

<template>
  <div>
    <header>
        <h1>안녕하세요, 제 이름은 '하프' 입니다.</h1>
        <h2>어서오세요! 제 소개 페이지에 오신 것을 환영합니다.</h2>
    </header>

    <section>
        <h2>자기 소개</h2>
        <p>안녕하세요! 저는 하프라고 합니다. 개발자로로 활동하고 있습니다. 취미로는 영화보는 문화생활을 즐기고 있습니다. 더 자세한 내용은 아래에서 확인해주세요.</p>
        <div class="contact-icons">
            <a href="mailto:you@example.com" target="_blank"><i class="far fa-envelope"></i></a>
            <a href="tel:+123456789" target="_blank"><i class="fas fa-phone-alt"></i></a>
            <a href="https://github.com/yourusername" target="_blank"><i class="fab fa-github"></i></a>
            <!-- 다른 아이콘 및 링크 추가 가능 -->
        </div>
    </section>

    <section>
        <h2>연락처</h2>
        <p>이메일: [이메일 주소]<br>
        휴대전화: [전화번호]</p>
    </section>

    <footer>
        <p>제작자: 하프 &copy; 2024</p>
    </footer>
  </div>
</template>

<style>
  body {
      margin: 0;
      padding: 0;
      background-color: #f0f0f0;
      color: #555;
  }

  header {
      background-color: #3498db;
      padding: 30px 0;
      text-align: center;
      color: #fff;
  }

  h1, h2 {
      margin: 0;
  }

  .print {
    cursor: pointer;
    width: 200px;
    height: 50px;
    margin-left: calc(50% - 100px);
    border-radius: 5px;
    border: 1px solid lightgray;
    background-color: #3498db;
    color: white;
    font-weight: bold;
    font-size: 20px;
  }

  section {
      max-width: 800px;
      margin: 30px auto;
      padding: 30px;
      background-color: #fff;
      border-radius: 10px;
      box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
  }

  h2 {
      color: #3498db;
  }

  p {
      line-height: 1.6;
  }

  footer {
      text-align: center;
      padding: 15px;
      background-color: #3498db;
      color: #fff;
      position: fixed;
      bottom: 0;
      width: 100%;
  }

  .contact-icons {
      display: flex;
      justify-content: center;
      margin-top: 20px;
  }

  .contact-icons a {
      color: #555;
      margin: 0 10px;
      font-size: 24px;
      text-decoration: none;
  }

  .contact-icons a:hover {
      color: #3498db;
  }
</style>

 

 

 

 

프린트 기능

1. vue3-print-nb

프린트 기능을 이용하기 위한 라이브러리로는 vue3-print-nb가 있습니다.

npm을 이용하셔서 사용하셔도 됩니다 😊

 

vue3-print-nb를 설치해주도록 합시다.

npm install vue3-print-nb --save

 

 

src/main.js

// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import print from 'vue3-print-nb'

const app = createApp(App)
app.use(print)
app.mount('#app')

 

 

src/app.vue

// src/App.vue
<template>
  <PrintFunc/>
</template>

<script>
import PrintFunc from './components/printFunc.vue';
export default {
  name: 'App',
  components: {
    PrintFunc
  }
}
</script>

 

 

src/printFunc.vue

<template>
  <!-- id 추가 -->
  <div id="printMe"> 
    <header>
        <h1>안녕하세요, 제 이름은 '하프' 입니다.</h1>
        <h2>어서오세요! 제 소개 페이지에 오신 것을 환영합니다.</h2>
    </header>
    [생략...]
    
    <footer>
        <p>제작자: 하프 &copy; 2024</p>
    </footer>
  </div>
  
  <!-- 출력 버튼 추가 -->
  <button v-print="'#printMe'" class="print">vue-print-nb</button>
</template>

 

 

 

프린트 버튼을 누르게 되면, 다음과 같이 뜨게 될 겁니다!

만약 배경색상이 안나온다고 한다면, 옵션에서 배경 그래픽이 선택되어 있는지 확인해주시면 되겠습니다!

 

 

 

2. print-js

이번에는 print-js 라이브러리를 사용하여 프린트 기능을 만들어보겠습니다.

마찬가지로 npm에서 문서를 보신 후 사용하셔도 됩니다 😊

 

 

print-js를 설치해주도록 합시다.

npm install print-js --save

 

 

그런 후 코드를 추가해주도록 합시다.

아래의 코드를 보면 maxWidth를 따로 설정해주었는데, 이는 기본값으로 800으로 되어 있어서 css수정 시 이상해지더라구요.

그래서 임의적으로 100%로 설정해주었습니다!

// src/components/printFunc.vue

<template>
[...생략]

  <!-- v-print 추가 -->
  <button v-print="'#printMe'" class="print">vue-print-nb</button>
  <button class="print" type="button" @click="printPage">print-js</button>
</template>


<script setup>
import printJS from 'print-js';
const printPage = () => {
  printJS({
    printable: 'printMe',
    type: 'html',
    targetStyles: ['*'],
    maxWidth: '100%',
  });
};
</script>

[...생략]

 

 

이렇게 작성한 후 저장하면!!

짜잔 버튼이 생겼네요

 

 

결과를 보니 다소 아쉬운면이 있는것 같네요.

저라면 vue-print-nb를 쓸 것 같습니다 😊

 

 

 

3. window.print()

window.print를 이용하여 출력하는 방법에는 두가지가 있습니다.

첫 번째로 현재 페이지에 출력하고자 하는 페이지를 덮어 씌우고 window.print를 하여 출력하는 방법과

두 번째로는 새 탭에 디자인을 전부 넣은 뒤 출력하는 방법입니다!

 

첫 번째의 경우는 하려고 했다가, 기각되었습니다 🥹

코드를 보면서 설명드리겠습니다.

const printContent = () => {
  const content = document.querySelector("#printMe").innerHTML;
  const originalContents = document.body.innerHTML;
  document.body.innerHTML = content;
  window.print();
  document.body.innerHTML = originalContents;
};

 

첫번째로 originalContents로 현재 페이지에 대한 정보를 백업시킨 후

복사하고자 하는 페이지(content)로 덮어 씌운 후 프린트를 합니다.

그런 후 다시 원래대로 되돌려 놓는 방식인데.. !

 

Vue3에서는 다시 되돌릴 때 클릭 이벤트마저 사라지더라구요 🥹

그래서 기각되었습니다... 

 

 

 

그래서!! 등장한 두번째 방법

새 탭을 띄운 후, 해당 탭에 스타일을 지정한 뒤 출력을 방식을 해보겠습니다.

 

새탭의 경우 css 스타일링이 적용이 안되어... 수동으로 해주어야 하는 번거러움이 있습니다 🥹

 

코드의 경우 다음과 같습니다!

// src/components/printFunc.vue

<template>
[...생략]

  <!-- v-print 추가 -->
  <button v-print="'#printMe'" class="print">vue-print-nb</button>
  <button class="print" type="button" @click="printPage">print-js</button>
  <button class="print" type="button" @click="windowPrint">window.print</button>
</template>


<script setup>
[...생략]
const windowPrint = () => {
  const content = printArea.value.innerHTML;
  const printWindow = window.open('', '_blank', 'width=700, height=600, top=50, left=50, scrollbars=yes');

  printWindow.document.open();
  printWindow.document.write(`
    <html>
    <style>
    body {
      margin: 0;
      padding: 0;
      background-color: #f0f0f0;
      color: #555;
    }

    header {
      background-color: #3498db;
      padding: 30px 0;
      text-align: center;
      color: #fff;
    }

    h1, h2 {
      margin: 0;
    }

    .print {
      cursor: pointer;
      width: 200px;
      height: 50px;
      margin-left: calc(50% - 100px);
      border-radius: 5px;
      border: 1px solid lightgray;
      background-color: #3498db;
      color: white;
      font-weight: bold;
      font-size: 20px;
    }

    section {
        max-width: 800px;
        margin: 30px auto;
        padding: 30px;
        background-color: #fff;
        border-radius: 10px;
        box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
    }

    h2 {
        color: #3498db;
    }

    p {
        line-height: 1.6;
    }

    footer {
        text-align: center;
        padding: 15px;
        background-color: #3498db;
        color: #fff;
        position: fixed;
        bottom: 0;
        width: 100%;
    }

    .contact-icons {
        display: flex;
        justify-content: center;
        margin-top: 20px;
    }

    .contact-icons a {
        color: #555;
        margin: 0 10px;
        font-size: 24px;
        text-decoration: none;
    }

    .contact-icons a:hover {
        color: #3498db;
    }
    </style>
    <head>
      <title>Print</title>
    </head>
    <body>${content}</body>
    </html>`
  );
  printWindow.document.close();
  // 프린트 창이 닫힐 때
  printWindow.onafterprint = () => {
    printWindow.close();
  };
  printWindow.print();
}

</script>

[...생략]

 

 

스타일링을 변수로 지정해주면 좀 더 깔끔하게 진행할 수 있을것 같네요!

onafterprint 함수를 사용해서 프린트 창이 닫힐 때, 새 탭이 같이 닫힐 수 있도록 설정해두었습니다 😊

 

새로 생긴 버튼을 클릭하게 되면!!

 

짜잔! 요렇게 새 탭에 스타일링이 적용되면서 출력이 됩니다.

 

 

 


요상하게 Vue의 경우는 프린트에 대한 한국어 자료가 별로 없더라구요 ..

그래서 요기 조기 찾아보느라 시간이 좀 많이 들었네요..

 

다른 분들에게 도움이 된다면 좋겠습니다 😊

 

 

🪶 깃허브

 

GitHub - hdev1004/vue3_print_function

Contribute to hdev1004/vue3_print_function development by creating an account on GitHub.

github.com