React 瀏覽器打印
近期着手項目任務的打印功能,在此作個記錄,本文介紹基於React的一種調用瀏覽器打印的方法。
整體思路: 通過構建一個隱藏的元素(該元素包裹需打印的內容),當打印行爲觸發時,將頁面其他的一些不需要打印的元素隱藏,然後將需打印的元素追加到body中,打印完成後,再恢復初始狀態即可。瀏覽器打印的本質還是將web頁面中的元素打印出來而已。
1. 構建待打印元素
在頁面中構建一個display爲none
的元素,裏面的內容爲你需要打印的內容。我們還需要設置包裹打印內容的元素的ref屬性
,以便於後面獲取到元素。
<div style={{ display: 'none' }}>
<div ref={el => (this.printRef = el)}>
{ 打印內容 }
</div>
</div>
2. 打印動作觸發時的處理
處理流程:
- 獲取待打印元素;
- 將根元素隱藏;
- 將待打印元素追加到body中;
- 調用瀏覽器的打印預覽;
- 預覽界面關閉後,將待打印元素從body中移除,將原始頁面恢復。
let printView = this.state.printRef //獲取待打印元素
document.querySelector('#root').className = 'print-hide' //將根元素隱藏
document.body.appendChild(printView) //將待打印元素追加到body中
window.print() //調用瀏覽器的打印預覽
document.body.removeChild(printView) //將待打印元素從body中移除
document.querySelector('#root').className = '' //將原始頁面恢復
對應的CSS設置:
@page {
size: A4;
margin: 0;
}
@media print {
html, body {
min-width: 0;
width: 210mm;
height: 297mm;
}
.print-hide {
visibility: hidden!important;
display: none!important;
}
}
其中,@page
中的size可以自己設置紙張的大小,如果是A4紙可以直接設置值爲A4
,媒體查詢@media print
中設置的是打印時的樣式,因爲打印設備知道其輸出區域的物理大小,所以使用釐米(cm)、毫米(mm)、英寸(in)等作爲打印設計的單位完全可行。
3. 注意點
- 第二小節的步驟2中的意思是:將頁面中所有不需要打印的元素隱藏,特別注意像模態窗Model這些元素,也要爲它們加上
'print-hide'
className屬性。 - 如果需要在特定位置強制分頁打印,可以嘗試在對應元素上設置
page-break-before:always !important
、page-break-after:always !important
CSS屬性,該屬性只對塊級元素有效。 - 進入打印預覽後,我們無法獲知用戶最終是選擇了打印,還是選擇了取消。這裏若有人知道解決方法的話,歡迎留言。