前端實(shí)現(xiàn)打印功能的兩種方法詳解
前言
前端實(shí)現(xiàn)打印功能的方法有很多,大家在網(wǎng)上隨便一搜就是一大堆,在這里,我主要選擇一個我覺得比較好一點(diǎn)的實(shí)現(xiàn)方式來進(jìn)行解釋描述:
方法一:window.print()
這個命令默認(rèn)打印整個頁面的內(nèi)容,所以,如果想要實(shí)現(xiàn)局部打印功能的話,就要重新給body賦值,并且后續(xù)執(zhí)行完之后再還原回去,這樣的話會造成一些非預(yù)期的結(jié)果,很麻煩,并且在當(dāng)前也操作,window.document.body的內(nèi)容重新渲染,打印完會有刷新,影響用戶的體驗(yàn),所以不推薦,但還是簡單介紹一下:
//(1)首先獲得元素的html內(nèi)容(這里建議如果有樣式最好是用內(nèi)聯(lián)樣式的方式) var newstr = document.getElementById(myDiv).innerHTML;//得到需要打印的元素HTML //(2)保存當(dāng)前頁面的整個html,因?yàn)閣indow.print()打印操作是打印當(dāng)前頁的所有內(nèi)容,所以先將當(dāng)前頁面保存起來,之后便于恢復(fù)。 var oldstr = document.body.innerHTML;//保存當(dāng)前頁面的HTML //(3)把當(dāng)前頁面替換為打印內(nèi)容HTML document.body.innerHTML = newstr; //(4)執(zhí)行打印操作 window.print(); //(5)還原當(dāng)前頁面 document.body.innerHTML = oldstr;
方法二:利用iframe,iframe.contentWindow.print()
這個與方法一的區(qū)別就是,取消打印后可以完整保留當(dāng)前訪問頁面的內(nèi)容,不需要影響原頁面,需要注意的是,在你生成新的iframe內(nèi)的html時,樣式可能會有影響,加載不完全(全局樣式特別),需要單獨(dú)引入一些你自己的樣式,我比較推薦這個,所以來重點(diǎn)說明一下:
// 1、獲取需要打印的部分
const printArea = this.getElementById(document.body,"rx-form-container");
// 2、引入打印的專有CSS樣式
var strStyleCSS="<link href='/rxform.css' type='text/css' rel='stylesheet'>";
var antdesignCSS="<link href='/antdesign.css' type='text/css' rel='stylesheet'>";
let printCSS=" <link href='/print.css' type='text/css' rel='stylesheet'> ";
// 3、拼接字符串
var strFormHtml=strStyleCSS +antdesignCSS + printCSS+"<body>"+domEl.innerHTML+"</body>";
// 4、創(chuàng)建 iframe 標(biāo)簽
var iframe = document.createElement('IFRAME');
var doc = null;
iframe.setAttribute('style','position:absolute;width:0;height:0;left:-500px;top:-500px;');
// 5、瀏覽器插入 iframe
document.body.appendChild(iframe);
doc = iframe.contentWindow.document;
// 引入打印的專有CSS樣式
// doc.write("<LINK rel='stylesheet' type='text/css' href='/print.css'>");
doc.write(printHTML);
doc.close();
iframe.contentWindow.focus();
// 注意:等待加載完調(diào)用打印,否則樣式外聯(lián)css顯示有問題
iframe.contentWindow.addEventListener('load', function() {
// 6、開始打印
iframe.contentWindow.print();
// 7、刪除iframe
document.body.removeChild(iframe);
})這樣寫雖然不會影響原頁面,但是需要我們把打印的內(nèi)容及樣式用JS來生成,如果打印的內(nèi)容很多,或者樣式很復(fù)雜的話,那就是一個大工程,難免不方便,所以如何解決問題呢?我在查度娘的時候,發(fā)現(xiàn)了一種方式:將要打印的內(nèi)容生成一個圖片然后放在iframe中,利用html2canvas 生成截圖,但是我并未校驗(yàn)(因?yàn)楸救隧?xiàng)目主要是打印表單流程,沒有很復(fù)雜,嘻嘻),所以,這里我就簡單復(fù)制一下大佬的,最后也放置了鏈接,如果有需要也可以去大佬博客看看:
// 打印賬單
printBill () {
this.printDisabled = true // 點(diǎn)擊打印按鈕禁止重復(fù)點(diǎn)擊
setTimeout(_ => { // 按鈕顯示為禁止了再去執(zhí)行截圖功能
html2canvas(this.$refs.reconciliationWrapper, {
backgroundColor: null,
scale: 1.3
}).then((canvas) => {
let dataURL = canvas.toDataURL('image/png')
this.$refs.iframe.contentWindow.document.body.innerHTML = '' // 清空上一次打印的內(nèi)容
this.$refs.iframe.contentWindow.document.write('<html><head><style media="print">@page { margin: 0mm 10mm; }body{margin-top: 50px; text-align: center;}</style></head><body><img src=' + dataURL + '></body></html>')
setTimeout(_ => {
this.$refs.iframe.contentWindow.print()
}, 0)
this.printDisabled = false
})
}, 100)
}然后將截圖放在iframe中的img打印,截圖一般會有些模糊,調(diào)整html2canvas的參數(shù)scale,放大縮小的比例,要根據(jù)實(shí)際情況調(diào)整。
補(bǔ)充:導(dǎo)出步驟
1:引入html2Canvas 和 JsPDF
import html2Canvas from 'html2canvas'; import JsPDF from 'jspdf';
2:實(shí)現(xiàn)導(dǎo)出
export() {
var printDom = document.getElementById('print');//獲取打印的節(jié)點(diǎn)
let opts: any = {
useCORS: true, // 表示允許跨越的圖片;allowTaint: true和useCORS: true選擇一個
// windowHeight: modal.scrollHeight + 24 + 100,//獲取y方向頁面包含滾動條的高度,24和100為padding,margin
// width: dom.offsetWidth + 48,//48為padding值
// height: dom.clientHeight + 400,//可見高度+padding+margin
// y: window.pageYOffset + 100,//滾動條高度修復(fù)
// scrollX: 17,
scale: 1
};
//html2Canvas的作用是根據(jù)dom生成屏幕截圖
html2Canvas(printDom, opts).then(canvas => {
let contentWidth = canvas.width;
let contentHeight = canvas.height;
let pageHeight = contentWidth / 592.28 * 841.89;
let leftHeight = contentHeight;
let position = 0;
let imgWidth = 595.28;
let imgHeight = 592.28 / contentWidth * contentHeight;
let pageData = canvas.toDataURL('image/jpeg', 1.0);
// landscape表示橫向,portrait表示縱向
let PDF = new JsPDF('portrait', 'pt', 'a4');//縱向
if (leftHeight < pageHeight) {
PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
} else {
while (leftHeight > 0) {
PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
leftHeight -= pageHeight;
position -= 841.89;
if (leftHeight > 0) {
PDF.addPage();
}
}
}
PDF.save(`導(dǎo)出內(nèi)容.pdf`);
})
}
總結(jié):
打印的方式很多,大家選擇適合自己項(xiàng)目的即可。就像王者榮耀,哈哈哈(肯定會有人突然疑惑,為什么會突然提到游戲,因?yàn)榍皟商煳铱祥_心自己粉絲在增加,但是感覺自己博客不怎么生動,同事就給了我一個建議,可以說說王者榮耀,嘻嘻嘻,第一次說,以后不一定啥時候說),所以最后總結(jié)只有第一句話有用,后邊大家隨便看看就行,代碼機(jī)器們,加油,在努力個四五十年,馬上就可以退休了?。?!
到此這篇關(guān)于前端實(shí)現(xiàn)打印功能的文章就介紹到這了,更多相關(guān)前端實(shí)現(xiàn)打印功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談javascript運(yùn)算符——條件,逗號,賦值,()和void運(yùn)算符
下面小編就為大家?guī)硪黄獪\談javascript運(yùn)算符——條件,逗號,賦值,()和void運(yùn)算符。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-07-07
JS圖片懶加載的優(yōu)點(diǎn)及實(shí)現(xiàn)原理
這篇文章主要介紹了JS圖片懶加載的優(yōu)點(diǎn)及實(shí)現(xiàn)原理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-01-01

