1. 程式人生 > >window.print()頁面列印之表格內容分頁填充進行分頁列印

window.print()頁面列印之表格內容分頁填充進行分頁列印

   windwow.print()用於列印當前視窗的內容,很簡便,可當內容特殊並且列印有特殊需求的時候就要繞個圈了。下面是需要列印的表格:


    當資料量少的時候像上面的表格一樣,中間的內容只有5條資料,打印出來在紙上會有空白,不太好。中間內容是不確定的可能幾十條,可能上百條,這樣迴圈在介面上展示是沒有問題的,但是當使用火狐列印時會按照表格的大小成倍的縮小,最後列印到一張紙上,字型和表格都會很小,當使用其他瀏覽器時它會自動將內容列印到下一張紙上,因為列印到紙上不可能沒有邊距,所以在紙與紙銜接的時候會存在資料丟失打印不出來的情況。

    經過測試,當每頁17條資料的時候打印出來可以滿頁填充,既不會所以為了使打印出來的表格更靠譜,更為使用者著想一些,在介面顯示的時候顯示的條目為實際的條目,列印時如果資料量少就進行自動空白填充,如果資料量大在保留標題、表格上半部分和下半部分的同時進行分頁填充列印,列印完成後再恢復原來的頁面。


實現思路:

1.使用列印分頁css,相當於分頁符,總是在此div後分頁

<div style="page-break-after:always"></div>

ps:關於page-break-after的使用:http://www.w3school.com.cn/cssref/pr_print_page-break-after.asp   需要特別注意的是它應用於:position 值為 relative 或 static 的非浮動塊級元素。當時absolute的時候是不起作用的。

2.將介面分為兩個div,一個div中用於進行介面展示,另一個div進行列印填充,兩個div

一個為介面展示時的樣式,另一個為列印時的樣式,單擊列印時頁面div隱藏,對另外一個div進行填充,列印方法執行完成後,頁面div顯示,另一個div隱藏。

3.將頁面div分為幾部分:
第一部分為標題內容部分,第二部分為表格上半部分是固定的,第三部分為資料部分,每頁的內容是不同的, 第四部分為表格下半部分,最後為表格下面的內容部分是固定的。

頁面展示div程式碼展示:

<div id="dataPrint" style="height:100%; margin-left:13px;margin-right:15px;display:none;">
  </div>
  <div id="dataPanel" style="position:absolute;left:50%;margin-left:-397px;">
  <div id="topContent">
	  <h2 style="width:794px;text-align:center">********資料憑單</h2><br>
	  <br>
	  <span style="margin-left:34px;">${currentDate}</span><span style="margin-left:510px;">NO:</span>
  </div>
    <table id="table" class="table table-bordered table-condensed table-hover" style="width:730px;margin-left:30px;border-width:4px;margin-top:5px;">
  	  <tbody id="firstContent">
  	    <tr>
  	      <td style="width: 10%;border-left-width:5px;text-align:center">姓    名</td>
  	      <td colspan='2'><input style="width: 100%;border-width:0" id="applicantName" value="${applicationInfo.applicant.name}"/></td>
  	      <td style="width: 20%;text-align:center">電    話</td>
  	      <td style="width: 20%"><input style="width: 100%;border-width:0" id="Phone" value="${applicationInfo.applicant.mobile}"/></td>
  	    </tr>
  	    <tr>
  	      <td style="word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center">單    位</td>
   	      <td colspan='2'><input style="width: 100%;border-width:0" id="WorkUnit" value="${applicationInfo.applicant.work_unit}"/></td>
          <td style="width: 19%;text-align:center">類    別</td>
  	      <td style="width: 19%;text-align:left">社內<input type="checkbox" style="margin-left:0" /> 軍內<input type="checkbox"  style="margin-left:0"/> 地方<input type="checkbox" style="margin-left:0" /></td>
  	    </tr>
  	    <tr>
          <td style="word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center">內    容</td>
  	      <td colspan='4'><input style="width: 100%;border-width:0" id="Content" value=""/></td>
  	    </tr>
  	    <tr>
  	      <td style="word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center">用    途</td>
   	      <td colspan='2'><input style="width: 100%;border-width:0" id="Content" value=""/></td>
          <td style="width: 20%;text-align:center">類    別</td>
  	      <td style="width: 20%;text-align:left">新聞<input type="checkbox" style="margin-left:0" /> 宣傳<input type="checkbox" style="margin-left:0" /> 商業<input type="checkbox" style="margin-left:0" /></td>
  	    </tr>
  	    <tr>
  	      <td style="word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center">序    號</td>
   	      <td style="width: 20%;text-align:center">底片號/畫報號</td>
          <td style="width: 20%;text-align:center">年    代</td>
  	      <td style="width: 20%;text-align:center">尺    寸</td>
  	      <td style="width: 20%;text-align:center">價    格</td>
  	    </tr>
  	  </tbody>
      <tbody id="secondContent">
  	    <!-- 迴圈開始 -->
  	    <c:if test="${applicationInfo.resType eq 'Picture'}">
  	      <c:forEach items="${applicationInfo.dataInfo}" var="item" varStatus="varStatus">
  	        <tr id="tr_${varStatus.index}"><!--pictorialInfo  -->
              <td style="word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center">${varStatus.index+1}</td>
  	          <td style="width: 20%;text-align:center"><input style="width: 100%;border-width:0" value="<fmt:formatDate value="${item.pictureInfo.negativeNo}" pattern="yyyy"/>"/></td>
  	          <td style="width: 20%;text-align:center"><fmt:formatDate value="${item.pictureInfo.shootDt}" pattern="yyyy" /></td>
  	          <td style="width: 20%;text-align:center">${item.pictureInfo.width}*${item.pictureInfo.height}</td>
  	          <td style="width: 20%;text-align:center"></td>
  	        </tr>
  	      </c:forEach>
  	    </c:if>
  	    <c:if test="${applicationInfo.resType eq 'PictureBook'}">
  	      <c:forEach items="${applicationInfo.dataInfo}" var="item" varStatus="varStatus">
  	        <tr id="tr_${varStatus.index}"><!-- pictureBookInfo -->
              <td style="word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center">${varStatus.index+1}</td>
  	          <td style="text-align:center"><input style="width: 100%;border-width:0" value=""/></td>
  	          <td style="text-align:center"></td>
  	          <td style="text-align:center"></td>
  	          <td style="text-align:center"></td>
  	        </tr>
  	      </c:forEach> 	   
  	    </c:if>
  	    <c:if test="${applicationInfo.resType eq 'Pictorial'}">
  	      <c:forEach items="${applicationInfo.dataInfo}" var="item" varStatus="varStatus">
  	        <tr id="tr_${varStatus.index}"><!-- pictorialInfo -->
              <td style="word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center">${varStatus.index+1}</td>
  	          <td style="text-align:center"><input style="width: 100%;border-width:0" value="${item.pictorialInfo.issueNo}"/></td>
  	          <td style="text-align:center"><fmt:formatDate value="${item.pictorialInfo.aId}" pattern="yyyy" /></td>
  	          <td style="text-align:center"></td>
  	          <td style="text-align:center"></td>
  	        </tr>
  	      </c:forEach>
  	    </c:if> 
  	  </tbody>
  	  <tbody id="thirdContent">
  	    <tr>
          <td style="word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center">總    計</td>
  	      <td colspan='4'></td>
  	    </tr>
  	    <tr>
          <td style="word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center">實    收</td>
  	      <td colspan='4'><span style="margin-left:33%"></span>大    寫:</td>
  	    </tr>
  	    <tr>
          <td style="word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center">組    長<br>意    見</td>
  	      <td colspan='4'></td>
  	    </tr>
  	    <tr>
          <td style="word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center">分管副主任<br>意    見</td>
  	      <td colspan='4'></td>
  	    </tr>
  	    <tr>
          <td style="word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center">主    任<br>意    見</td>
  	      <td colspan='4'></td>
  	    </tr>
  	    <tr>
          <td style="word-wrap:break-word;border-left-width:5px;" colspan='5'><span style="margin-left:13px"></span>接    待:<span style="margin-left:200px"></span>制    作:<span style="margin-left:200px"></span>收    銀:</td>
  	    </tr>
      </tbody>
    </table>
    <div id="footerContent">
	    <span style="margin-left:33px;margin-top:-5px">地    址:北京市阜外大街34號
	      <span style="margin-left:5px"></span>***********
	      <span style="margin-left:51px"></span>電    話:***********
	      <span style="margin-left:50px"></span>軍    線:***********
	    </span>
    </div>
    </div>


列印js拼接佈局程式碼展示:

function doPrint() {
      //隱藏按鈕,避免按鈕被打印出來
      $("#btnPre").hide();
      $("#btnNext").hide();
      $("#btnon").hide();
      $("#btnBack").hide();
      $("#btnPreView").hide();
      var html_bak = document.getElementById("dataPanel").innerHTML;
      preparePrintTable();
      window.print();
      document.getElementById("dataPanel").innerHTML = html_bak;
      $("#dataPanel").show();
      $("#dataPrint").html();
      $("#dataPrint").hide(); 
      $("#btnPre").show();
      $("#btnNext").show();
      $("#btnon").show();
      $("#btnBack").show();
      $("#btnPreView").show();
     } 
   
    function preparePrintTable() {
      //隱藏原表格
      $("#dataPanel").hide();
      var pageItemNum = 17; 
      //滿頁數
      var pages=parseInt('${applicationInfo.dataInfo.size()}' / pageItemNum);
      $("#dataPrint").html();
      var newTableDiv;
      var html_tbl;
      html_tbl = "";
      var head_comp;
      var head_table_comp;
      var tail_table_comp;
      var tail_comp;
      var newTable;
      //獲取原table的class和style屬性
      var tbl_cls = $("#table").attr("class");
      var tbl_sty = $("#table").attr("style");
      head_comp = document.getElementById("topContent").outerHTML;
      tail_comp = document.getElementById("footerContent").outerHTML;
      head_table_comp = document.getElementById("firstContent").outerHTML;
      tail_table_comp = document.getElementById("thirdContent").outerHTML;
      for(i=0; i < pages ; i++){ //last page will be handled in the way;
	     //建立新的table
        newTable = document.createElement("table");
	 	newTable.setAttribute('class',tbl_cls);
	    newTable.setAttribute('style',tbl_sty);
	 	//新增中間資料部分
	 	var newTableTrs="";
	  	for(j=i*pageItemNum; j < (i+1)*pageItemNum; j++){
           if(document.getElementById("tr_" + j) == null) {
             break;
           }
           newTableTrs += document.getElementById("tr_" + j).outerHTML;
           console.log("newTableTrs="+newTableTrs);
        }
	 	//新增表格內容
        newTable.innerHTML=head_table_comp+newTableTrs+tail_table_comp;
	 	//表格內容部分div
	 	newTableDiv = document.createElement("div");
	    newTableDiv.innerHTML=head_comp+newTable.outerHTML+tail_comp;
	    //換行符
	    sep = document.createElement("div");
        sep.setAttribute("style","page-break-after:always");
        //新增換行符調節第二頁標題位置
        var br = document.createElement("br");
        var newDiv=newTableDiv.outerHTML+sep.outerHTML+br.outerHTML;
        html_tbl += newDiv;
      }
      //prepare last page;
      var leftItemNum = parseInt('${applicationInfo.dataInfo.size()}' % pageItemNum);
      if(leftItemNum > 0) {
        newTable = document.createElement("table");
	    newTable.setAttribute('class',tbl_cls);
	    newTable.setAttribute('style',tbl_sty);
	 	//新增中間資料部分
	 	var newTableTr="";
	 	var newTableEmtTrs="";
	 	for(j=pages * pageItemNum; j < ${applicationInfo.dataInfo.size()}; j++){
          if(document.getElementById("tr_" + j) == null) {
            break;
          }
          newTableTr += document.getElementById("tr_" + j).outerHTML;;
        }
        var emptyTr;
        var emptyTd;
        for(k=0; k < pageItemNum - leftItemNum; k++){
          newTableEmtTrs +=createEmptyTr(j + k);
        }
        console.log("newTableEmtTrs="+newTableEmtTrs);
        var tbody_comp = createEmptyTr(pageItemNum - leftItemNum);
        newTable.innerHTML=head_table_comp+newTableTr+newTableEmtTrs+tail_table_comp;
	    newTableDiv = document.createElement("div"); 
	    newTableDiv.innerHTML=head_comp+newTable.outerHTML+tail_comp;
        html_tbl += newTableDiv.outerHTML;
      }
      document.getElementById("dataPrint").innerHTML = html_tbl;
      $("#dataPrint").show();
    }
 
    function createEmptyTr(idx) {
       var emptyTr;
       var emptyTd;
       emptyTr = document.createElement("tr");
       emptyTr.setAttribute("style","word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center");
       emptyTd = document.createElement("td");
       emptyTd.setAttribute("style","word-wrap:break-word;width: 10%;border-left-width:5px;text-align:center");
       emptyTd.innerHTML="  ";
       var tra= emptyTd.outerHTML;
      
       emptyTd = document.createElement("td");
       emptyTd.setAttribute("style","text-align:center");
       var trb= emptyTd.outerHTML;
       
       emptyTd = document.createElement("td");
       emptyTd.setAttribute("style","text-align:center");
       var trc= emptyTd.outerHTML;
       
       emptyTd = document.createElement("td");
       emptyTd.setAttribute("style","text-align:center");
       var trd= emptyTd.outerHTML;
         
       emptyTd = document.createElement("td");
       emptyTd.setAttribute("style","text-align:center");
       var tre= emptyTd.outerHTML;
       emptyTr.innerHTML=tra+trb+trc+trd+tre;
       return emptyTr.outerHTML;
    }

ps:之所以使用innerHTML和outerHTML是因為使用IE或者360瀏覽器時append方法不相容報錯,不然拼接內容時直接append就可以了,像

head_table_comp = document.getElementById("firstContent");

newTable.append(head_table_comp);

這樣就可以,如果對瀏覽器要求不高的話使用append的方式比較好。


去掉web列印時自帶的頁首頁尾以及url:

<style media="print">
    @page {
      size: auto;  /* auto is the initial value */
      margin: 0mm; /* this affects the margin in the printer settings */
    }
</style>

最後效果圖:

 

小結:

    進行分頁列印的時候也是走一步一個坑,開始分頁div新增進去了,但是並沒有分頁,火狐自動縮小,解決了火狐的問題,發現IE和360js程式碼不相容,前臺經常會因為種種需求拼接介面,在這個過程中鍛鍊了自己邏輯思維和前臺程式碼拼接的能力,寫此部落格作為自己專案成長的印記以及分享。