vue-print-preview
v2.0.2
Published
๐จ๏ธ Professional Vue3 print preview component - Commercial license required
Downloads
19
Maintainers
Readme
Vue Print Preview
๐จ๏ธ ๋ธ๋ผ์ฐ์ ์ธ์ ์ฌ๋ฐฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ Vue 3 ์ธ์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
Vue Print Preview๋ ์ค์ ์ธ์๋ฌผ๊ณผ ์ ํํ ์ผ์นํ๋ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ์ ๊ณตํ์ฌ ๋ธ๋ผ์ฐ์ ๋ณ ์ธ์ ์ฌ๋ฐฑ ๋ถ์ผ์น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค.
๐ ๋ฒ์ ์ ๋ณด
v2.0.2 (ํ์ฌ ๋ฒ์ )
- ๐ง ์ ํํ ๋์ด ์ธก์ ์ค๋ฅ ํด๊ฒฐ
v2.0.1
- ๐ง ์คํ์ผ ๊ด๋ จ ์ค๋ฅ ํด๊ฒฐ, ํ์ด์ง ๋ ๋๋ง ํ์ด๋ฐ ๋ฌธ์ ํด๊ฒฐ
- ๐ง ์ ํํ ๋์ด ์ธก์ ์คํจ ์ค๋ฅ ํด๊ฒฐ์ค
v2.0.0
์ฃผ์ ๋ณ๊ฒฝ์ฌํญ (Breaking Changes):
- ๐ ์ปดํฌ๋ํธ ์ด๋ฆ ๋ณ๊ฒฝ:
PrintPreviewScreenโ<preview-pages> - ๐จ Tailwind CSS ์์ ์ง์: iframe ์ธ์์์ Tailwind ํด๋์ค ์๋ ์ ์ฉ
- ๐ ๋์ด ์ธก์ ์์ ํ:
getBoundingClientRect()๊ธฐ๋ฐ ์ ๋ฐ ๋์ด ๊ณ์ฐ - ๐ง margin collapse ์ฒ๋ฆฌ: ๋ณต์กํ CSS ๋ ์ด์์์์ ์ ํํ ํ์ด์ง ๋ถํ
v1.0.0 - 2025๋ 8์ ์ถ์
- ๐ฏ ๊ธฐ๋ณธ A4 ์ธ์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๊ธฐ๋ฅ
- ๐ ๋ค์ํ ์ฉ์ง ํฌ๊ธฐ ์ง์ (A4, A3, B3, Letter)
- ๐ ๋ค๋จ ์ปฌ๋ผ ๋ ์ด์์ (1-3๋จ)
- ๐จ ํค๋/ํธํฐ ์์คํ
โจ ์ฃผ์ ๊ธฐ๋ฅ
- ๐ฏ ์ ํํ ์ธ์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ - ์ค์ ์ธ์๋ฌผ๊ณผ 100% ์ผ์นํ๋ ํ๋ฉด ๋ฏธ๋ฆฌ๋ณด๊ธฐ
- ๐จ Tailwind CSS ์์ ์ง์ - CDN ์๋ ๋ก๋ฉ์ผ๋ก ์คํ์ผ ์๋ฒฝ ์ฌํ (v2.0.0)
- ๐ ์ ๋ฐ ๋์ด ์ธก์ - border, margin, box-shadow ํฌํจ ์ ํํ ํ์ด์ง ๋ถํ (v2.0.0)
- ๐ ๋ค์ํ ์ฉ์ง ํฌ๊ธฐ - A4, A3, B3, Letter ํ๋ฆฌ์ ๋ฐ ์ปค์คํ ํฌ๊ธฐ ์ง์
- ๐ ๋ค๋จ ์ปฌ๋ผ ๋ ์ด์์ - 1-3๋จ ์ปฌ๋ผ ์๋ ๋ถํ ๋ฐ ๊ท ๋ฑ ๋ฐฐ์น
- ๐ ์๋ ํ์ด์ง ๋ถํ - DOM ๋์ด ๊ธฐ๋ฐ ์ง๋ฅํ ํ์ด์ง ๋๋๊ธฐ
- ๐จ ํค๋/ํธํฐ ์์คํ - ํ์ด์ง๋ณ ํค๋, ์๋จ, ํธํฐ ํ ํ๋ฆฟ ์ง์
- ๐ฑ ๋ฐ์ํ ์ค์ผ์ผ๋ง - ์ปจํ ์ด๋ ํฌ๊ธฐ์ ๋ฐ๋ฅธ ์ค์๊ฐ ํฌ๊ธฐ ์กฐ์
- ๐ง TypeScript ์ง์ - ์์ ํ ํ์ ์์ ์ฑ ๋ณด์ฅ
๐ฆ ์ค์น
npm install vue-print-preview๐ ๋น ๋ฅธ ์์
๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
<template>
<preview-pages
preset="A4"
:content="htmlContent"
/>
</template>
<script setup>
import { PreviewPages } from 'vue-print-preview'
const htmlContent = `
<h1>์ ๋ชฉ</h1>
<p>์ธ์ํ ๋ด์ฉ์
๋๋ค.</p>
`
</script>์ปค์คํ ์ฌ๋ฐฑ ์ค์
<template>
<preview-pages
preset="A4"
:content="htmlContent"
:custom-margins="{
top: 25,
right: 20,
bottom: 25,
left: 20,
columns: 2,
columnGap: 15
}"
/>
</template>์์ ์ปค์คํ ์ฉ์ง ์ค์
<template>
<preview-pages
:paper-config="{
width: 200,
height: 280,
margins: { top: 15, right: 10, bottom: 15, left: 10 },
columns: 2,
columnGap: 12,
name: 'Custom Size'
}"
:content="htmlContent"
/>
</template>ํค๋/ํธํฐ ์ฌ์ฉ
<template>
<preview-pages
preset="A4"
:content="htmlContent"
:header="headerHTML"
:page-top="pageTopHTML"
:footer="footerHTML"
/>
</template>
<script setup>
const headerHTML = `
<div style="text-align: center; border-bottom: 2px solid #333;">
<h1>๋ฌธ์ ์ ๋ชฉ</h1>
</div>
`
const pageTopHTML = `
<div style="text-align: right;">
ํ์ด์ง {{pageNumber}}/{{totalPages}}
</div>
`
const footerHTML = `
<div style="text-align: center;">
ยฉ 2025 My Company
</div>
`
</script>๐ API ๋ฌธ์
Props
| ์์ฑ | ํ์
| ๊ธฐ๋ณธ๊ฐ | ์ค๋ช
|
|------|------|--------|------|
| preset | 'A4' \| 'A3' \| 'B3' \| 'LETTER' | 'A4' | ํ์ค ์ฉ์ง ํฌ๊ธฐ ํ๋ฆฌ์
|
| paperConfig | PaperConfig | - | ์์ ์ปค์คํ
์ฉ์ง ์ค์ |
| customMargins | CustomMargins | - | ํ๋ฆฌ์
๊ธฐ๋ฐ ๋ถ๋ถ ์์ |
| content | string | - | ์ธ์ํ HTML ์ฝํ
์ธ |
| header | string | - | ์ฒซ ํ์ด์ง ํค๋ HTML |
| pageTop | string | - | ๋ชจ๋ ํ์ด์ง ์๋จ HTML |
| footer | string | - | ๋ชจ๋ ํ์ด์ง ํ๋จ HTML |
ํ์ ์ ์
interface PaperConfig {
width: number // mm ๋จ์
height: number // mm ๋จ์
margins: {
top: number // mm ๋จ์
right: number // mm ๋จ์
bottom: number // mm ๋จ์
left: number // mm ๋จ์
}
columns?: number // ์ปฌ๋ผ ์ (1-3)
columnGap?: number // mm ๋จ์
name?: string // ์ฉ์ง ์ด๋ฆ
}
interface CustomMargins {
top?: number // mm ๋จ์
right?: number // mm ๋จ์
bottom?: number // mm ๋จ์
left?: number // mm ๋จ์
columns?: number // ์ปฌ๋ผ ์
columnGap?: number // mm ๋จ์
}๐ ๊ณ ๊ธ ์ฌ์ฉ๋ฒ
ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์ ์ธ์
<template>
<preview-pages
ref="printRef"
preset="A4"
:content="content"
/>
<button @click="handlePrint">์ธ์ํ๊ธฐ</button>
</template>
<script setup>
import { ref } from 'vue'
const printRef = ref()
const handlePrint = () => {
if (printRef.value) {
printRef.value.printPreview()
}
}
</script>๋ค๋จ ์ปฌ๋ผ ๋ ์ด์์
<template>
<preview-pages
preset="A4"
:custom-margins="{
columns: 3, // 3๋จ ์ปฌ๋ผ
columnGap: 8 // 8mm ๊ฐ๊ฒฉ
}"
:content="columnContent"
/>
</template>๐จ ์คํ์ผ๋ง
๋ชจ๋ ํฌ๊ธฐ์ ์ฌ๋ฐฑ์ mm ๋จ์๋ก ํต์ผ๋์ด ์์ด ์ธ์๋ฌผ๊ณผ ์ ํํ ์ผ์นํฉ๋๋ค.
/* ๊ธ๋ก๋ฒ CSS์์ ์ฌ์ฉ์ ์ ์ ์คํ์ผ */
.print-page-wrapper {
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.print-page {
font-family: 'Noto Sans KR', sans-serif;
}๐ ์ฌ์ฉ ์์
์ํ์ง ๋ ์ด์์
<template>
<preview-pages
preset="A4"
:content="examContent"
:header="examHeader"
:footer="examFooter"
:custom-margins="{
top: 30,
columns: 2,
columnGap: 15
}"
/>
</template>
<script setup>
const examHeader = `
<div style="text-align: center; border-bottom: 2px solid #000;">
<h1>2025ํ๋
๋ ๋ชจ์์ํ</h1>
<h2>์ํ ์์ญ</h2>
</div>
`
const examFooter = `
<div style="text-align: right; font-size: 10pt;">
ํ์ด์ง {{pageNumber}} / {{totalPages}}
</div>
`
</script>๐ก ํ๊ณผ ์๋ น
- mm ๋จ์ ์ฌ์ฉ: ๋ชจ๋ ํฌ๊ธฐ๋ mm ๋จ์๋ก ์ค์ ํ์ฌ ์ธ์ ์ ํ๋๋ฅผ ๋ณด์ฅํฉ๋๋ค.
- ํค๋/ํธํฐ ํ
ํ๋ฆฟ:
{{pageNumber}}์{{totalPages}}๋ณ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. - ์ปฌ๋ผ ์ต์ ํ: 1-3๋จ ์ปฌ๋ผ์ ์ง์ํ๋ฉฐ, ์ปฌ๋ผ ๊ฐ๊ฒฉ์ 8-15mm๊ฐ ๊ถ์ฅ๋ฉ๋๋ค.
- ๋ฐ์ํ ๋ฏธ๋ฆฌ๋ณด๊ธฐ: ์ปจํ ์ด๋ ํฌ๊ธฐ์ ๋ฐ๋ผ ์๋์ผ๋ก ์ค์ผ์ผ์ด ์กฐ์ ๋ฉ๋๋ค.
๐ ๏ธ ์์คํ ์๊ตฌ์ฌํญ
- Vue: 3.5.18+
- TypeScript: 5.7.2+ (์ ํ์ฌํญ)
- ๋ธ๋ผ์ฐ์ : Chrome 90+, Firefox 88+, Safari 14+
๐ ๋ผ์ด์ผ์ค
์ด ์ํํธ์จ์ด๋ ๋ ์ ๋ผ์ด์ผ์ค ํ์ ๋ฐฐํฌ๋ฉ๋๋ค. ์์ ์ ์ฌ์ฉ ๋ฐ ์ฌ๋ฐฐํฌ์ ๋ํ ์์ธํ ๋ด์ฉ์ ๊ฐ๋ฐ์์๊ฒ ๋ฌธ์ํ์ธ์.
๐จโ๐ป ๊ฐ๋ฐ์
hoonee-math
- ๐ ํฌํธํด๋ฆฌ์ค: https://hoonee-math.info
- ๐ง ๋ฌธ์: ํฌํธํด๋ฆฌ์ค ์ฌ์ดํธ๋ฅผ ํตํด ์ฐ๋ฝ ๊ฐ๋ฅ
Vue Print Preview๋ ์ ํํ ์ธ์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ํตํด ๋ ๋์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํฉ๋๋ค.
