2013-10-28 33 views
10

我有一個使用AngularJS的html頁面,我想打印一個div。有沒有一種方法可以做到這一點? ..或它`只是經典的JavaScript以下方式:是否有從HTML頁面打印div的有效方法?

<script language="javascript" type="text/javascript"> 
    function printDiv(divID) { 
     //Get the HTML of div 
     var divElements = document.getElementById(divID).innerHTML; 
     //Get the HTML of whole page 
     var oldPage = document.body.innerHTML; 

     //Reset the page's HTML with div's HTML only 
     document.body.innerHTML = 
     "<html><head><title></title></head><body>" + 
     divElements + "</body>"; 

     //Print Page 
     window.print(); 

     //Restore orignal HTML 
     document.body.innerHTML = oldPage; 
     } 
    </script> 

如果AngularJS沒有解決這個事情,您能否做鄰的方式,不使用JavaScript函數(例如:doc.getElementById( ))..一種接近AngularJS方法的方法?

THX,

+0

創建打印指令,也可以使用'angular.element' – tymeJV

+0

我不會把以上代碼的事業的所有事件上/ JavaScript的數據表示HTML丟失?你可以做基本相同的事情,而不會通過使用iframe或以同樣的方式打開新窗口而丟失所述信息。 –

+0

最後,我用ng-hide指令完成了它(用於隱藏所有我不想打印的元素),並在我的控制器中調用windows.print()函數。在我看來,這是迄今爲止最好的解決方案。 –

回答

16

我創建了一個簡單的指令打印使用iframe的技術DIV內容。這有點駭人聽聞,但效果很好。在我看來,沒有更好的辦法可以做到這一點。該指令的腳本是:

'use strict'; 

angular.module('yourAppNameHere').directive('printDiv', function() { 
    return { 
    restrict: 'A', 
    link: function(scope, element, attrs) { 
     element.bind('click', function(evt){  
     evt.preventDefault();  
     PrintElem(attrs.printDiv); 
     }); 

     function PrintElem(elem) 
     { 
     PrintWithIframe($(elem).html()); 
     } 

     function PrintWithIframe(data) 
     { 
     if ($('iframe#printf').size() == 0) { 
      $('html').append('<iframe id="printf" name="printf"></iframe>'); // an iFrame is added to the html content, then your div's contents are added to it and the iFrame's content is printed 

      var mywindow = window.frames["printf"]; 
      mywindow.document.write('<html><head><title></title><style>@page {margin: 25mm 0mm 25mm 5mm}</style>' // Your styles here, I needed the margins set up like this 
          + '</head><body><div>' 
          + data 
          + '</div></body></html>'); 

      $(mywindow.document).ready(function(){ 
      mywindow.print(); 
      setTimeout(function(){ 
       $('iframe#printf').remove(); 
      }, 
      2000); // The iFrame is removed 2 seconds after print() is executed, which is enough for me, but you can play around with the value 
      }); 
     } 

     return true; 
     } 
    } 
    }; 
}); 

在模板您標記​​這樣的打印按鈕:

<a href="#" print-div=".css-selector-of-the-div-you-want-to-print">Print!</a> 

就是這樣,它應該工作。 由於沒有跨瀏覽器的方式來檢測打印執行的結束,因此您會發現運行所需的時間太長,因此這個黑客部分是因爲iFrame在一定的毫秒數之後被移除。

您可能需要包含jQuery才能正常工作,我不確定,因爲如果沒有它,我幾乎從不工作。我添加了一些內聯評論以使事情更清楚。我使用this answer的一些代碼,它使用彈出窗口來打印div內容(但不包括Angular.js)。也許你會更喜歡這種方法。

+0

我試了很多關於Google的指令。這是公平的易於使用,它的工作。謝謝。 –

+0

這是一個乾淨的解決方案,不需要jQuery插件!謝謝,真的很有用 – Michelangelo

+0

@MladenDanic雖然我非常喜歡這個解決方案,但我似乎無法加載外部css樣式表。我不得不使用html樣式標籤。任何解決這個問題的方法?我有很多造型要做:)...它變得很快凌亂。 – Michelangelo

5

我需要這在IE8工作+

'use strict'; 

angular 
.module('print-div', []) 
.directive('printDiv', function() { 
    return { 
     restrict: 'A', 
     link: function(scope, element, attrs) { 

      var iframe; 
      var elementToPrint = document.querySelector(attrs.printDiv); 

      if (!window.frames["print-frame"]) { 
       var elm = document.createElement('iframe'); 
       elm.setAttribute('id', 'print-frame'); 
       elm.setAttribute('name', 'print-frame'); 
       elm.setAttribute('style', 'display: none;'); 
       document.body.appendChild(elm); 
      } 

      function write(value) { 
       var doc; 
       if (iframe.contentDocument) { // DOM 
        doc = iframe.contentDocument; 
       } else if (iframe.contentWindow) { // IE win 
        doc = iframe.contentWindow.document; 
       } else { 
        alert('Wonder what browser this is... ' + navigator.userAgent); 
       } 
       doc.write(value); 
       doc.close(); 
      } 

      element.bind('click', function(event) { 
       iframe = document.getElementById('print-frame'); 
       write(elementToPrint.innerHTML); 

       if (window.navigator.userAgent.indexOf ("MSIE") > 0) { 
        iframe.contentWindow.document.execCommand('print', false, null); 
       } else { 
        iframe.contentWindow.focus(); 
        iframe.contentWindow.print(); 
       } 
      }); 
     } 
    }; 
}); 
+0

我不能相信這一點。 IE總是很痛苦。第一個答案似乎工作,直到我在IE中測試這個。這做得好嗎?我的意思是在其他瀏覽器中沒有問題? – Michelangelo

-1

angularPrint是角指令這是超級好用。 https://github.com/samwiseduzer/angularPrint

你只是裝點你的HTML,其自定義屬性:

<div> 
    <div print-section> 
    I'll print 
    <p>Me, too!</p> 
    </div> 
    <div>I won't</div> 
</div> 
+0

看起來像一個有許多開放問題的死亡項目 –