vue中實(shí)現(xiàn)打印功能的幾種方法示例
1、直接調(diào)用 window.print()方法
這種方法默認(rèn)打印整個(gè)頁面,不能打印局部頁面。并且不保留原有樣式
<!doctype html> <html> <head> <meta charset="utf-8"> <title>打印測(cè)試頁</title> <style type="text/css" media="screen"> .pageheader, .pagefooter { display: none; } </style> <style type="text/css" media="print"> /*每一頁 如果沒有另外自定義的話 */ @page { margin-left: 50px; margin-top: 100px; } /*第一頁*/ @page :first { margin-left: 50%; margin-top: 50%; } /*分頁標(biāo)記*/ .geovindu { page-break-after: always; } .pageheader { margin-top: 10px; font-size: 12pt; } .pagefooter { margin-top: 10px; font-size: 10pt; } </style> </head> <body> <script type="text/javascript"> function main() { window.print(); } </script> <div id="geovindu" class="geovindu"> <div class="pageheader">頁眉:打印測(cè)試</div> <div class="conent"> 封面內(nèi)容 </div> <div class="pagefooter">頁腳:第1頁/共2頁</div> </div> <div id="geovindu" class="geovindu"> <div class="pageheader">頁眉:打印測(cè)試</div> <div class="conent"> 第二頁內(nèi)容 </div> <div class="pagefooter">頁腳:第2頁/共2頁</div> </div> <button onclick="main()">打印按鈕</button> </body> </html>
2、自定義封裝打印方法
這種方法也是調(diào)用了原生打印,通過封裝好方法,可以指定需要打印的區(qū)域,自由度高,缺點(diǎn)就是通過截取全頁面的html進(jìn)行字符串截取,并且不保留原有樣式,需要去手動(dòng)添加樣式。
2.1、封裝打印方法,創(chuàng)建一個(gè)printHtml.js文件
export default function printHtml(html) { let style = getStyle(); let container = getContainer(html); document.body.appendChild(style); document.body.appendChild(container); getLoadPromise(container).then(() => { window.print(); document.body.removeChild(style); document.body.removeChild(container); }); } // 設(shè)置打印樣式 function getStyle() { let styleContent = `#print-container { display: none; } @media print { body > :not(.print-container) { display: none; } html, body { display: block !important; } #print-container { display: block; } }`; let style = document.createElement("style"); style.innerHTML = styleContent; return style; } // 清空打印內(nèi)容 function cleanPrint() { let div = document.getElementById('print-container') if (!!div) { document.querySelector('body').removeChild(div) } } // 新建DOM,將需要打印的內(nèi)容填充到DOM function getContainer(html) { cleanPrint() let container = document.createElement("div"); container.setAttribute("id", "print-container"); container.innerHTML = html; return container; } // 圖片完全加載后再調(diào)用打印方法 function getLoadPromise(dom) { let imgs = dom.querySelectorAll("img"); imgs = [].slice.call(imgs); if (imgs.length === 0) { return Promise.resolve(); } let finishedCount = 0; return new Promise(resolve => { function check() { finishedCount++; if (finishedCount === imgs.length) { resolve(); } } imgs.forEach(img => { img.addEventListener("load", check); img.addEventListener("error", check); }) }); }
2.2、使用方式
<template> <div> <button @click="onPrint">打印1</button> // dom部分 可用if控制 <i test='printStart'></i> <div v-show="oldStr"> v-show1的 </div> <div v-show="oldStr"> v-show2的 </div> 測(cè)試沖沖沖 <div class="xwtable"> <table> <tr> <th>序號(hào)</th> <th>姓名</th> <th>年齡</th> <th>性別</th> <th>手機(jī)</th> <th>郵箱</th> <th>地址</th> <th>工齡</th> <th>崗位</th> <th>薪資</th> </tr> <tr v-for="(item, index) in list" key="index"> <td>{{ index + 1}}</td> <td>{{ item.name }}</td> <td>{{ item.age }}</td> <td>{{ item.sex }}</td> <td>{{ item.phone }}</td> <td>{{ item.mail }}</td> <td>{{ item.address }}</td> <td>{{ item.workAge }}</td> <td>{{ item.jobs }}</td> <td>{{ item.salary }}</td> </tr> </table> </div> <i test='printEnt'></i> <div> <div class="text_styte">我是測(cè)試樣式的</div> </div> </div> </template> <script setup lang="ts"> // 引入封裝好的打印函數(shù) import printHtml from "./printHtml.js"; import { ref } from 'vue'; let oldStr = ref(false); let editableIs = ref(true); let showChang = ref(true); let list = [{ name: "阿噠", age: 26, sex: "男", phone: "12345678901", mail: "mmm@mmm.com", address: "藍(lán)星星國馬爾哈哈海島", workAge: 2, jobs: "研發(fā)", salary: "1.8k" }, { name: "阿榮", age: 24, sex: "男", phone: "12345678901", mail: "mmm@mmm.com", address: "藍(lán)星星國馬爾哈哈海島", workAge: 1, jobs: "研發(fā)", salary: "1.8k" }, { name: "阿豪", age: 26, sex: "男", phone: "12345678901", mail: "mmm@mmm.com", address: "藍(lán)星星國馬爾哈哈海島", workAge: 5, jobs: "產(chǎn)品", salary: "1.8k" }, { name: "阿晨", age: 29, sex: "男", phone: "12345678901", mail: "mmm@mmm.com", address: "藍(lán)星星國馬爾哈哈海島", workAge: 9, jobs: "設(shè)計(jì)", salary: "1.8k" }, { name: "阿震", age: 30, sex: "男", phone: "12345678901", mail: "mmm@mmm.com", address: "藍(lán)星星國馬爾哈哈海島", workAge: 7, jobs: "銷售", salary: "1.8k" }, { name: "阿鋒", age: 21, sex: "男", phone: "12345678901", mail: "mmm@mmm.com", address: "藍(lán)星星國馬爾哈哈海島", workAge: 0.1, jobs: "售后", salary: "1.8k" } ] // 點(diǎn)擊處理打印 const onPrint = () => { editableIs.value = false; //以上用于關(guān)閉不需要打印的部分 最簡(jiǎn)單的方法是給dom v-if,不需要贅述吧 showChang.value = true; //雙向綁定需要給頁面渲染時(shí)間,延遲一定時(shí)間 setTimeout(function () { // document.title = '標(biāo)題 | 這是頁眉標(biāo)題哦'; // 獲取body的內(nèi)容 let oldStr = window.document.body.innerHTML; // 開始打印標(biāo)識(shí), 21個(gè)字符 注意"" let start = '<i test="printStart">'; // 結(jié)束打印標(biāo)識(shí), 23個(gè)字符 let end = '<i test="printEnt"></i>'; let condition = true let printData = '' while (condition) { if (oldStr.indexOf(start) == -1) { condition = false } else { // 截取開始打印標(biāo)識(shí)之后的內(nèi)容 let newStr = oldStr.substr(oldStr.indexOf(start) + 21); // 截取開始打印標(biāo)識(shí)和結(jié)束打印標(biāo)識(shí)之間的內(nèi)容 printData = printData + newStr.substring(0, newStr.indexOf(end)); // 截取結(jié)束打印標(biāo)識(shí)之后的內(nèi)容 oldStr = newStr.substr(newStr.indexOf(end) + 23); } } let reg = new RegExp("display: none", "g"); //定義正則表達(dá)式 printData = printData.replace(reg, '') // 調(diào)用打印 printHtml(printData) }, 500) } </script> <style scoped> .xwtable { width: 100%; border-collapse: collapse; border: 1px solid #ccc; } .xwtable thead td { font-size: 12px; color: #333333; text-align: center; background: url(table_top.jpg) repeat-x top center; border: 1px solid #ccc; font-weight: bold; } .xwtable tbody tr { background: #fff; font-size: 12px; color: #666666; } .xwtable tbody tr.alt-row { background: #f2f7fc; } .xwtable td { line-height: 20px; text-align: left; padding: 4px 10px 3px 10px; height: 18px; border: 1px solid #ccc; } </style>
3、使用vue3-print-nb依賴
這個(gè)方法可以自定義打印區(qū)域,并且保留原有樣式,缺點(diǎn)是打印區(qū)域的樣式不能和打印區(qū)域外的樣式相關(guān)聯(lián)。同事我們也可以在通過@media print
來對(duì)需要打印的區(qū)域進(jìn)行樣式設(shè)置,自由度比較好一些,具體更多使用方式還是大家一起去發(fā)掘。
這里使用的是vue3+ts的引入和使用方式,vue2的引入方式可以去看看別的文章。
3.1、全局引入方式
// main.ts import { createApp } from "vue"; import App from "./App.vue"; import Print from 'vue3-print-nb' createApp(App).use(Print).mount("#app");
3.2、局部引入方式(setup)自定義指令--------------(推薦)
網(wǎng)上有很多<script lang="ts">
或者<script>
的使用自定義指令的方式這里就不再贅述了。
<script setup lang="ts"> import print from 'vue3-print-nb' // 使用自定義指令 const vPrint = print let prints = { id: 'print-iframe', popTitle: '配置頁眉標(biāo)題', // 打印配置頁上方的標(biāo)題 extraHead: '', // 最上方的頭部文字,附加在head標(biāo)簽上的額外標(biāo)簽,使用逗號(hào)分割 preview: false, // 是否啟動(dòng)預(yù)覽模式,默認(rèn)是false previewTitle: '預(yù)覽的標(biāo)題', // 打印預(yù)覽的標(biāo)題 previewPrintBtnLabel: '預(yù)覽結(jié)束,開始打印', // 打印預(yù)覽的標(biāo)題下方的按鈕文本,點(diǎn)擊可進(jìn)入打印 zIndex: 20002, // 預(yù)覽窗口的z-index,默認(rèn)是20002,最好比默認(rèn)值更高 previewBeforeOpenCallback() { console.log('正在加載預(yù)覽窗口!'); }, // 預(yù)覽窗口打開之前的callback previewOpenCallback() { console.log('已經(jīng)加載完預(yù)覽窗口,預(yù)覽打開了!') }, // 預(yù)覽窗口打開時(shí)的callback // 開始打印之前的callback beforeOpenCallback() { console.log('開始打印之前!') }, openCallback() { console.log('執(zhí)行打印了!') }, // 調(diào)用打印時(shí)的callback closeCallback() { console.log('關(guān)閉了打印工具!'); var element = document.getElementById("print-iframe"); element?.parentNode?.removeChild(element); }, // 關(guān)閉打印的callback(無法區(qū)分確認(rèn)or取消) clickMounted() { console.log('點(diǎn)擊v-print綁定的按鈕了!') }, standard: '', extarCss: '' } </script>
3.3、簡(jiǎn)單直接使用場(chǎng)景
我們?cè)谛枰蛴〉膆tml標(biāo)簽上添加在
prints
對(duì)象里定義的id屬性 ,通過在按鈕加上v-print="prints"
自定義指令實(shí)現(xiàn)打印。
<template> <button v-print="prints">打印2</button> <div id="print-iframe"> // dom部分 可用if控制 <div class="xwtable"> <table> <tr> <th>序號(hào)</th> <th>姓名</th> <th>年齡</th> <th>性別</th> <th>手機(jī)</th> <th>郵箱</th> <th>地址</th> <th>工齡</th> <th>崗位</th> <th>薪資</th> </tr> <tr v-for="(item, index) in list" key="index"> <td>{{ index + 1}}</td> <td>{{ item.name }}</td> <td>{{ item.age }}</td> <td>{{ item.sex }}</td> <td>{{ item.phone }}</td> <td>{{ item.mail }}</td> <td>{{ item.address }}</td> <td>{{ item.workAge }}</td> <td>{{ item.jobs }}</td> <td>{{ item.salary }}</td> </tr> </table> </div> <div> <div class="text_styte">我是測(cè)試樣式的</div> </div> </div> </template> <script setup lang="ts"> // 引入封裝好的打印函數(shù) import print from 'vue3-print-nb' import { ref } from 'vue'; const vPrint = print let prints = { id: 'print-iframe', popTitle: '配置頁眉標(biāo)題', // 打印配置頁上方的標(biāo)題 extraHead: '', // 最上方的頭部文字,附加在head標(biāo)簽上的額外標(biāo)簽,使用逗號(hào)分割 preview: false, // 是否啟動(dòng)預(yù)覽模式,默認(rèn)是false previewTitle: '預(yù)覽的標(biāo)題', // 打印預(yù)覽的標(biāo)題 previewPrintBtnLabel: '預(yù)覽結(jié)束,開始打印', // 打印預(yù)覽的標(biāo)題下方的按鈕文本,點(diǎn)擊可進(jìn)入打印 zIndex: 20002, // 預(yù)覽窗口的z-index,默認(rèn)是20002,最好比默認(rèn)值更高 previewBeforeOpenCallback() { console.log('正在加載預(yù)覽窗口!'); }, // 預(yù)覽窗口打開之前的callback previewOpenCallback() { console.log('已經(jīng)加載完預(yù)覽窗口,預(yù)覽打開了!') }, // 預(yù)覽窗口打開時(shí)的callback // 開始打印之前的callback beforeOpenCallback() { console.log('開始打印之前!') }, openCallback() { console.log('執(zhí)行打印了!') }, // 調(diào)用打印時(shí)的callback closeCallback() { console.log('關(guān)閉了打印工具!'); var element = document.getElementById("print-iframe"); element?.parentNode?.removeChild(element); }, // 關(guān)閉打印的callback(無法區(qū)分確認(rèn)or取消) clickMounted() { console.log('點(diǎn)擊v-print綁定的按鈕了!') }, standard: '', extarCss: '' } let list = [{ name: "阿噠", age: 26, sex: "男", phone: "12345678901", mail: "mmm@mmm.com", address: "藍(lán)星星國馬爾哈哈海島", workAge: 2, jobs: "研發(fā)", salary: "1.8k" }, { name: "阿榮", age: 24, sex: "男", phone: "12345678901", mail: "mmm@mmm.com", address: "藍(lán)星星國馬爾哈哈海島", workAge: 1, jobs: "研發(fā)", salary: "1.8k" }, { name: "阿豪", age: 26, sex: "男", phone: "12345678901", mail: "mmm@mmm.com", address: "藍(lán)星星國馬爾哈哈海島", workAge: 5, jobs: "產(chǎn)品", salary: "1.8k" }, { name: "阿晨", age: 29, sex: "男", phone: "12345678901", mail: "mmm@mmm.com", address: "藍(lán)星星國馬爾哈哈海島", workAge: 9, jobs: "設(shè)計(jì)", salary: "1.8k" }, { name: "阿震", age: 30, sex: "男", phone: "12345678901", mail: "mmm@mmm.com", address: "藍(lán)星星國馬爾哈哈海島", workAge: 7, jobs: "銷售", salary: "1.8k" }, { name: "阿鋒", age: 21, sex: "男", phone: "12345678901", mail: "mmm@mmm.com", address: "藍(lán)星星國馬爾哈哈海島", workAge: 0.1, jobs: "售后", salary: "1.8k" } ] // 點(diǎn)擊處理打印 </script> <style scoped> .xwtable { width: 100%; border-collapse: collapse; border: 1px solid #ccc; } .xwtable thead td { font-size: 12px; color: #333333; text-align: center; background: url(table_top.jpg) repeat-x top center; border: 1px solid #ccc; font-weight: bold; } .xwtable tbody tr { background: #fff; font-size: 12px; color: #666666; } .xwtable tbody tr.alt-row { background: #f2f7fc; } .xwtable td { line-height: 20px; text-align: left; padding: 4px 10px 3px 10px; height: 18px; border: 1px solid #ccc; } </style>
3.4、在打印前處理需要打印的內(nèi)容區(qū)域
- 在觸發(fā)打印前我們需要做一些事情,我們可以通過創(chuàng)建兩個(gè)button標(biāo)簽點(diǎn)擊觸發(fā)處理事件后在執(zhí)行打印功能。
- 并且我們也可以創(chuàng)建一個(gè)新的dom節(jié)點(diǎn)去存放相要打印的內(nèi)容,重新渲染到頁面上再執(zhí)行打印。
<template> <div> <button ref="printRef" v-print="prints">打印2</button> <button @click="onClick">打印3</button> <div id="printArea"> <div class="text_styte">我是測(cè)試樣式的</div> <Auto></Auto> </div> </div> </template> <script setup lang="ts"> import Auto from "./Auto.vue"; import print from 'vue3-print-nb' import { ref } from 'vue'; const vPrint = print let printRef = ref(); let prints = { id: 'print-iframe', popTitle: '配置頁眉標(biāo)題', // 打印配置頁上方的標(biāo)題 extraHead: '', // 最上方的頭部文字,附加在head標(biāo)簽上的額外標(biāo)簽,使用逗號(hào)分割 preview: false, // 是否啟動(dòng)預(yù)覽模式,默認(rèn)是false previewTitle: '預(yù)覽的標(biāo)題', // 打印預(yù)覽的標(biāo)題 previewPrintBtnLabel: '預(yù)覽結(jié)束,開始打印', // 打印預(yù)覽的標(biāo)題下方的按鈕文本,點(diǎn)擊可進(jìn)入打印 zIndex: 20002, // 預(yù)覽窗口的z-index,默認(rèn)是20002,最好比默認(rèn)值更高 previewBeforeOpenCallback() { console.log('正在加載預(yù)覽窗口!'); }, // 預(yù)覽窗口打開之前的callback previewOpenCallback() { console.log('已經(jīng)加載完預(yù)覽窗口,預(yù)覽打開了!') }, // 預(yù)覽窗口打開時(shí)的callback // 開始打印之前的callback beforeOpenCallback() { console.log('開始打印之前!') }, openCallback() { console.log('執(zhí)行打印了!') }, // 調(diào)用打印時(shí)的callback closeCallback() { console.log('關(guān)閉了打印工具!'); var element = document.getElementById("print-iframe"); element?.parentNode?.removeChild(element); }, // 關(guān)閉打印的callback(無法區(qū)分確認(rèn)or取消) clickMounted() { console.log('點(diǎn)擊v-print綁定的按鈕了!') }, standard: '', extarCss: '' } const onClick = () => { test() printRef.value.click() } const test = () => { let iframe = document.createElement("div"); iframe.setAttribute("id", "print-iframe"); iframe.setAttribute( "style", "width: 100%; height: 100%; z-index: -9999; border: 0; margin: 0; padding: 0; " ); // 創(chuàng)建節(jié)點(diǎn) document.body.appendChild(iframe); //獲取目標(biāo)節(jié)點(diǎn) let targetDom = document.getElementById("printArea"); console.log(targetDom); let temp = `<div class="text_styte">我是測(cè)試樣式的22222222222</div> <div id="pageFooter">Page </div>`; temp += targetDom?.innerHTML temp += targetDom?.innerHTML temp += targetDom?.innerHTML temp += targetDom?.innerHTML temp += targetDom?.innerHTML temp += targetDom?.innerHTML temp += targetDom?.innerHTML iframe.innerHTML = temp } </script>
總結(jié)
到此這篇關(guān)于vue中實(shí)現(xiàn)打印功能的幾種方法的文章就介紹到這了,更多相關(guān)vue實(shí)現(xiàn)打印功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何配置vue.config.js 處理static文件夾下的靜態(tài)文件
這篇文章主要介紹了如何配置vue.config.js 處理static文件夾下的靜態(tài)文件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06vue-cli基礎(chǔ)配置及webpack配置修改的完整步驟
這篇文章主要給大家介紹了關(guān)于vue-cli基礎(chǔ)配置及webpack配置修改的完整步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用vue-cli具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10vue+Vue Router多級(jí)側(cè)導(dǎo)航切換路由(頁面)的實(shí)現(xiàn)代碼
這篇文章主要介紹了vue+Vue Router多級(jí)側(cè)導(dǎo)航切換路由(頁面)的實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12el-table表頭添加勾選框的實(shí)現(xiàn)示例
本文主要介紹了el-table表頭添加勾選框的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01