前端vue3打印功能實(shí)現(xiàn)(多頁(yè)打印、不使用插件)
說(shuō)下總體思路,創(chuàng)建一個(gè)組件,里面放多個(gè)span字段,然后根據(jù)父組件傳入的參數(shù),生成子組件,最好我們打印子組件的信息即可。通過(guò)我多次ai,探索最后成功了。
子組件代碼
@media print 這個(gè)我要講一下,這是控制在打印界面,打印的參數(shù),這是css中的知識(shí),我一開(kāi)始不曉得,慢慢問(wèn)ai和網(wǎng)上查資料曉得的。
<template>
<div id="printable-area">
<div v-for="(item, index) in printData" :key="index" class="print-item">
<div class="centered-content" style="font-size: 40px; margin-top: 55px">
圖號(hào):<span style="border-bottom: 1px solid black; display: inline-block; width: 300px;">{{ item.figureNumber }}</span><br>
名稱(chēng):<span style="border-bottom: 1px solid black; display: inline-block; width: 300px;">{{ item.name }}</span><br>
編號(hào):<span style="border-bottom: 1px solid black; display: inline-block; width: 300px; ">{{ item.number }}</span><br>
研制階段:<span style="border-bottom: 1px solid black; display: inline-block; width: 300px; ">{{ item.developmentPhase }}</span><br>
出廠時(shí)間:<span style="border-bottom: 1px solid black; display: inline-block; width: 300px; ">{{ item.factoryTime }}</span><br>
</div>
<br>
<div v-if="index < printData.length - 1" class="page-break"></div>
</div>
</div>
</template>
<script>
import {defineComponent} from 'vue';
export default defineComponent({
props: {
queryParam: Array
},
setup(props) {
const printData = props.queryParam;
return { printData };
}
});
</script>
<style>
@media print {
body {
background: none !important;
text-align: center; /* 讓 body 內(nèi)容居中 */
}
@page {
size: 15cm 12cm; /* 設(shè)置紙張大小為A4 */
margin:0; /* 設(shè)置頁(yè)邊距 */
}
.noprint {
display: none;
}
body {
background: none !important;
}
.page-break {
page-break-before: always;
}
}
</style>父組件
這是element 抽屜,我是為了看參數(shù)有沒(méi)有傳入進(jìn)去,用來(lái)測(cè)試的。我是通過(guò)一個(gè)按鈕,來(lái)實(shí)現(xiàn)對(duì)子組件傳參,把參數(shù)傳給子組件。
<div id="printArea">
<el-drawer v-model="drawer" title="I am the title" :with-header="false">
<Print ref="printComponent" :query-param="printData"></Print>
</el-drawer>
</div><el-button type="success" plain @click="print">打印</el-button>
這里也很關(guān)鍵,中間我遇到一個(gè)問(wèn)題,那就是經(jīng)常第一次點(diǎn)擊按鈕,dom元素沒(méi)有加載完,就彈出打印框了,所以我加了一個(gè)異步事件,還有記得把抽屜關(guān)了。
//這里獲取后端參數(shù)
state.drawer = true
// 使用nextTick確保DOM更新后執(zhí)行
nextTick(() => {
const printableElement = document.querySelectorAll('.print-item');
console.log(printableElement);
func.getPrint()
// 確保在抽屜隱藏之前獲取到元素
state.drawer = false;
});func.getPrint() 就是我打印功能實(shí)際實(shí)現(xiàn),為什么我這里是func,因?yàn)楣景阉蟹椒ǘ挤旁趂un里面,節(jié)約了導(dǎo)出,免得一個(gè)個(gè)導(dǎo)出。我們要用直接點(diǎn)就行了。
中間注釋的,是windo打印的方法,但是不曉得為啥子,關(guān)于打印的分頁(yè)功能沒(méi)有實(shí)現(xiàn),我其實(shí)很迷惑。
但是使用這個(gè)popupWin就成功了。
講一下大概思路,因?yàn)槲仪岸藢?xiě)了比較少,所以理解這些還是花了一點(diǎn)點(diǎn)時(shí)間。
querySelectorAll 因?yàn)槲覀兘M件有class名字,根據(jù)class名字獲取 了nodelist,一個(gè)元素?cái)?shù)組。其實(shí)每個(gè)元素?cái)?shù)組中就是前端的信息。
對(duì)了千萬(wàn)不要使用querySelectorOne,我ai生成的時(shí)候,發(fā)現(xiàn)為什么只打印了一個(gè)信息,一開(kāi)始我以為是我分頁(yè)沒(méi)有生效,其實(shí)是我只獲取了一個(gè)node。
const printableHTML = Array.from(printableElement).map(el => {
return el.outerHTML;
}).join('');這是獲取子組件的html元素,因?yàn)閚ode節(jié)點(diǎn),里面要通過(guò)outerHTML才能獲取,反正里面也有很多方法,可以看看,我有點(diǎn)記不到了。
后面的思路就簡(jiǎn)單,開(kāi)一個(gè)新窗口,然后把你從子節(jié)點(diǎn)獲取的html元素放到這個(gè)窗口中,然后打印這個(gè)窗口,最后實(shí)現(xiàn)。
getPrint:()=>{
const printableElement = document.querySelectorAll('.print-item');
console.log(printableElement);
// 將 NodeList 轉(zhuǎn)換為字符串,并添加分頁(yè)符
// const printableHTML = Array.from(printableElement).map(el => {
// return `<div style="page-break-after: always;">${el.outerHTML}</div>`;
// }).join('');
const printableHTML = Array.from(printableElement).map(el => {
return el.outerHTML;
}).join('');
// console.log(printableHTML)
// let bodyHtml = document.body.innerHTML //獲取整個(gè)頁(yè)面內(nèi)容
// document.body.innerHTML = printableHTML
// window.print() //打印
// document.body.innerHTML = bodyHtml//還原頁(yè)面內(nèi)容
// location.reload()
const popupWin = window.open('', '_blank', 'width=700,height=1000,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no');
popupWin.document.write(`
<html>
<head>
<title>Print tab</title>
<style>
body {
background: none !important;
text-align: center; /* 讓 body 內(nèi)容居中 */
}
@media print {
.noprint {
display: none;
}
@page {
size: 18cm 15cm; /* 設(shè)置紙張大小為A4 */
margin:0; /* 設(shè)置頁(yè)邊距 */
}
.noprint {
display: none;
}
.page-break {
page-break-before: always;
}
}
</style>
</head>
<body>
${printableHTML}
</body>
</html>
`);
popupWin.document.close();
popupWin.focus();
popupWin.print();
popupWin.close();
},最后我給大家放下效果圖,還有多多點(diǎn)贊,我為了完成這個(gè)功能,網(wǎng)上看了博客,都沒(méi)找到。
雖然最好我是通過(guò)ai加上自己人腦慢慢摸索的,哈哈。

總結(jié)
到此這篇關(guān)于前端vue3打印功能實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)前端vue3打印內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于VUE點(diǎn)擊父組件按鈕跳轉(zhuǎn)到子組件的問(wèn)題及解決方案
本文主要介紹了在Vue框架中,如何通過(guò)父組件的點(diǎn)擊事件打開(kāi)子組件中的彈窗并展示表格內(nèi)容,主要步驟包括在父組件中定義數(shù)據(jù)屬性,創(chuàng)建并定義子組件的彈窗和表格內(nèi)容,通過(guò)props屬性和自定義事件實(shí)現(xiàn)父子組件間的數(shù)據(jù)傳遞和方法調(diào)用2024-10-10
基于vue+element實(shí)現(xiàn)全局loading過(guò)程詳解
這篇文章主要介紹了基于vue+element實(shí)現(xiàn)全局loading過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
VUE 文字轉(zhuǎn)語(yǔ)音播放的實(shí)現(xiàn)示例
本文主要介紹了VUE 文字轉(zhuǎn)語(yǔ)音播放的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
vue實(shí)現(xiàn)錨點(diǎn)跳轉(zhuǎn)及滾動(dòng)監(jiān)聽(tīng)的方法
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)錨點(diǎn)跳轉(zhuǎn)及滾動(dòng)監(jiān)聽(tīng)的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
vue項(xiàng)目前端錯(cuò)誤收集之sentry教程詳解
Sentry 是一個(gè)開(kāi)源的錯(cuò)誤追蹤工具,可以幫助開(kāi)發(fā)人員實(shí)時(shí)監(jiān)控和修復(fù)系統(tǒng)中的錯(cuò)誤。這篇文章主要介紹了vue項(xiàng)目前端錯(cuò)誤收集之sentry,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05
前端實(shí)現(xiàn)pdf預(yù)覽功能的全過(guò)程(基于vue)
這篇文章主要給大家介紹了關(guān)于前端實(shí)現(xiàn)pdf預(yù)覽功能的相關(guān)資料,前端實(shí)現(xiàn)預(yù)覽最好的效果還是PDF,不會(huì)出現(xiàn)一些文字錯(cuò)亂和亂碼的問(wèn)題,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09
vue?filters和directives訪問(wèn)this的問(wèn)題詳解
這篇文章主要介紹了vue?filters和directives訪問(wèn)this的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01

