Существует ли Angular способ печати div с HTML-страницы?

У меня есть html-страница, использующая AngularJS, и я хочу напечатать div из нее. Есть ли способ Angular сделать это?.. или это просто классический javascript путь ниже:

    <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 HTML with div 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?

спасибо,

Ответ 1

Я создал простую директиву для печати содержимого div с использованием техники iframe. Это немного хакерское, но работает очень хорошо. нет лучшего способа сделать это, на мой взгляд. Директива script:

'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 contents are added to it and the iFrame 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, чтобы он работал, я не уверен, поскольку я почти никогда не работаю без него. Я добавил некоторые встроенные комментарии, чтобы сделать вещи более ясными. Я использовал код этого ответа, который использует всплывающее окно для печати содержимого div (но вне Angular.js). Возможно, вам понравится этот подход.

Ответ 2

Мне нужно было работать в 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();
                }
            });
        }
    };
});

Ответ 3

angularPrint - это директива angular, которая очень проста в использовании. https://github.com/samwiseduzer/angularPrint

вы просто украшаете свой html своими пользовательскими атрибутами:

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