2013-10-28 32 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

看起来像一个有许多开放问题的死亡项目 –