蘇州高端網(wǎng)站設(shè)計(jì)企業(yè)滕州今日頭條新聞
相信大家平時(shí)做項(xiàng)目時(shí),打印需求很常見(jiàn),但想把打印做好,還是要花點(diǎn)時(shí)間的。特別是長(zhǎng)列表要分頁(yè)的情況。
我們知道瀏覽原生 API `window.print()`
?可以用于印當(dāng)前窗口(window.document)視圖內(nèi)容。調(diào)用此方法會(huì)產(chǎn)生一個(gè)打印預(yù)覽彈框,用戶可以根據(jù)具體設(shè)置來(lái)得到打印結(jié)果。
一、window的打印事件
默認(rèn)情況下,調(diào)用 window.print() 會(huì)對(duì)整個(gè) document.body 進(jìn)行打印,當(dāng)需要打印指定容器內(nèi)容時(shí),可以這樣做:
1、先獲取指定容器中的內(nèi)容,將body的內(nèi)容替換掉,調(diào)用了打印方法后,再把原來(lái)的body恢復(fù)。
<body><div id="container1"><p>這是第一個(gè)段落</p></div><div id="container2"><p>這是第二個(gè)段落</p></div><input type="button" value="打印此頁(yè)面" onclick="printPage()" /><script>const printPage= () => {let newstr = document.getElementById("container1").innerHTML;let oldstr = document.body.innerHTML;document.body.innerHTML = newstr;window.print();document.body.innerHTML = oldstr;</script>
</body>
2、監(jiān)聽(tīng)打印前、后事件實(shí)現(xiàn)區(qū)域打印
window.onbeforeprint()、window.onafterprint()
<body><div id="container"><p>這是一個(gè)段落</p><h1 id="title">這是一個(gè)標(biāo)題</h1></div><input type="button" value="打印此頁(yè)面" onclick="printPage()" /><script>const printPage= () => {window.print();}// 打印前事件window.onbeforeprint = function() {// 隱藏不需要打印的元素document.getElementById('title').style.display = 'none';}// 打印完成后window.onafterprint = function() {// 放開(kāi)隱藏的元素document.getElementById('title').style.display = 'block';}</script>
</body>
二、打印樣式
?我們頁(yè)面的樣式和打印頁(yè)面時(shí)的樣式是兩個(gè)不同的樣式,打印時(shí)會(huì)默認(rèn)攜帶頁(yè)面的樣式,同時(shí)呢我們也可以修改頁(yè)面打印時(shí)的樣式。修改打印樣式的方法:
1、使用內(nèi)聯(lián)media屬性
<style media="print">.container{width:800px;}
</style>
2、使用媒體查詢
<style>@media print {h1{color: #333;background: #ccc;}}
</style>
3、引入打印樣式表?
?例如:print.css
@media print {@page {size: auto;margin: 20px 30px;}#mainBody{margin-top:0 !important;margin-bottom:0 !important;}
}
?用link引入
<link rel="stylesheet" type="text/css" href="./css/print.css" media="print" />
注意:
1、如果是前后不分離的項(xiàng)目,在樣式中用到`@`時(shí)可能會(huì)報(bào)錯(cuò):"上下文中未定義@media或@page",這時(shí)候我們可以用`<link>`的方式引入。
2、修改打印樣式時(shí)必須確保打印機(jī)樣式實(shí)際上確實(shí)覆蓋了主樣式表??梢允褂?important。
3、@page屬性可以控制打印頁(yè)面的邊距大小和頁(yè)眉頁(yè)腳
@media print {@page {size: auto; // {size:A4}、{size: 800px 1200px}、{size:portrait}豎向打印、{size:landscape}橫向打印margin: 20px 30px; // 邊距,可去除頁(yè)眉頁(yè)腳}// 覆蓋頁(yè)面原有樣式#container{margin-top:0 !important;margin-bottom:0 !important;} }
4、-webkit-print-color-adjust:是一個(gè)在瀏覽器中強(qiáng)制打印背景顏色和字體顏色的css屬性,當(dāng)打印出來(lái)的某些元素的背景顏色沒(méi)有被顯示時(shí),可以使用
-webkit-print-color-adjust:exact
5、
當(dāng)需要自定義打印分頁(yè)時(shí)機(jī)時(shí),可通過(guò)如下方式將指定 DOM 設(shè)為分割點(diǎn)。@media print {h1 {page-break-before: always; //在指定元素前面添加分頁(yè)符}#title {page-break-after: always;//在指定元素后面添加分頁(yè)符} }
了解更多:page-break-after - CSS:層疊樣式表 | MDN
?三、長(zhǎng)列表打印
打印長(zhǎng)列表時(shí)會(huì)要求自動(dòng)分頁(yè),但添加了分頁(yè)符效果可能并不理想。最常見(jiàn)的就是表格行被從中間截?cái)?#xff0c;那要怎么解決呢?
其實(shí)我們只要控制打印的行數(shù)就可以了。我們需要知道打印元素的高度和表格行的高度,算出一頁(yè)紙可以打印多少行,超出的部分放到下一頁(yè)打印。(一頁(yè)放多少行沒(méi)必要計(jì)算,根據(jù)打印元素的高度估算下就可以了。)
示例:
<style>body {font-family: "微軟雅黑",Verdana,SimHei,"Microsoft JhengHei",Tahoma;line-height: 1.5;background-color: #ffffff;margin: 0;}// 打印容器#mainBody {margin: 20px 20px 0 20px;}table {border: 1px solid #000;border-collapse: collapse;width: 100%;}table td {border: 1px solid #000;height: 30px;text-align: center;}table th {border: 1px solid #000;height: 30px;text-align: center;}.printContainer {margin: 0 auto;// 打印內(nèi)容寬高width: 1052px;height: 1480px;position: relative;}.printTitle {font-size: 22px;font-weight: bold;text-align: center;}.printnav {display: flex;justify-content: space-between;}.signature_footer {position: absolute;width: 100%;bottom: -20px;display: flex;justify-content: space-around;font-size: 20px;}
</style>
<body><div id="mainBody"></div>
</body><script>$(document).ready(function () {getList()})//獲取地址欄參數(shù)function getUrlParam(name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //構(gòu)造一個(gè)含有目標(biāo)參數(shù)的正則表達(dá)式對(duì)象var r = window.location.search.substr(1).match(reg);? //匹配目標(biāo)參數(shù)if (r != null) return unescape(r[2]); return null; //返回參數(shù)值}// 將列表數(shù)據(jù)分頁(yè),array要分頁(yè)的數(shù)據(jù),subNum是每頁(yè)多少條(根據(jù)紙張大小估算一頁(yè)能展示多少條)function groupArray(array, subNum) {let index = 0let newArray = []while (index < array.length) {newArray.push(array.slice(index, (index += subNum)))}return newArray}// 獲取數(shù)據(jù)源,頁(yè)面添加元素function getList() {var params = {PatientID: getUrlParam('PatientID'),BedNo: getUrlParam('BedNo'),xdStartDate: getUrlParam('StartDate'),xdEndDate: getUrlParam('EndDate')}$.get('/IndexPrintList', params, function (res) {// 先清空上一次的數(shù)據(jù)$('#mainBody').empty()// 分頁(yè)的數(shù)據(jù),返回的數(shù)組長(zhǎng)度即頁(yè)數(shù)var arr = groupArray(res.alist, 14)if (arr.length) {for (let i = 0; i < arr.length; i++) {// 創(chuàng)建打印元素$('#mainBody').append(`<div class="printContainer"><div class="printTitle">${res.hospitalName}</div><div style="text-align:center;font-weight:bold;font-size:20px;margin:20px 0;">定點(diǎn)血糖記錄表</div><div class="printnav" style="margin: 10px 0; font-size:14px;"><div>患者ID: ${res.patientModel.no}</div><div>姓名:${res.patientModel.name}</div><div>性別: ${res.patientModel.sex == 0 ? "男" : "女"}</div><div>病區(qū):${res.patientModel.Bed.WardModel.wardName}</div><div>床號(hào):${res.patientModel.Bed.innerOrder}</div><div>測(cè)量次數(shù):${res.allNum}</div></div><div class="printContent"><table><thead><tr><th colspan="2">日期\監(jiān)測(cè)點(diǎn)</th>${res.SortList.map(column => {return `<th>${column.name}</th>`}).join("")}</tr></thead><tbody>${arr[i].map(row => {return `<tr><td rowspan="3" style="width:90px">${row.measureTime}</td><td>血糖值(mmol/L)</td>${res.MeasurePointList.map(point => {if (row.dict[point.id]) {return `<td style="color:${row.dict[point.id].color}"> ${row.dict[point.id].Value}</td>`} else {return `<td></td>`}}).join("")}</tr><tr><td>操作者</td>${res.MeasurePointList.map(point => {if (row.dict[point.id]) {return `<td>${row.dict[point.id].AccountName}</td>`} else {return `<td></td>`}}).join("")}</tr><tr><td>測(cè)量時(shí)間</td>${res.MeasurePointList.map(point => {if (row.dict[point.id]) {return `<td>08:00</td>`} else {return `<td></td>`}}).join("")}</tr>`}).join("")}</tbody></table></div><div class="signature_footer"><div>醫(yī)生手簽:</div><div style="margin-right:30px;">質(zhì)控護(hù)士手簽:</div></div></div>`)}}window.print();})}</script>
代碼解釋:
1、首先給打印元素設(shè)置寬和高,高度根據(jù)需要或?qū)嶋H情況設(shè)置。(可根據(jù)A4紙大小來(lái)定)
2、通過(guò)接口拿到長(zhǎng)列表數(shù)據(jù),然后用`groupArray`方法計(jì)算需要打印幾頁(yè)。(groupArray函數(shù)返回一個(gè)二維數(shù)據(jù),二維數(shù)組的長(zhǎng)度就是頁(yè)數(shù),二維數(shù)組的每一項(xiàng)就是每頁(yè)的數(shù)據(jù))
3、根據(jù)這個(gè)二維數(shù)組循環(huán)創(chuàng)建要打印的元素。(類`.printContainer`是要打印的整體內(nèi)容,即一頁(yè)紙的內(nèi)容,arr[i]就是每頁(yè)的表格數(shù)據(jù))
4、示例中每頁(yè)都加了標(biāo)題和簽名,表格有合并單元格。
5、簡(jiǎn)單表格如下:
<table><thead><tr><th>檢測(cè)日期</th><th>檢測(cè)值</th><th>操作護(hù)士</th></tr></thead><tbody>${arr[i].map(item=>{return `<tr><td>${item.MeasureDateStr}</td><td>${item.value}</td><td>${item.AccountName}</td></tr>`}).join("")}</tbody>
</table>