web-dev-qa-db-fra.com

Imprimer une div à l'aide de javascript dans l'application d'une page angularJS

J'ai une seule application Web utilisant angularJS. J'ai besoin d'imprimer une div de certaines pages ..__J'ai essayé ce qui suit:

La page contient peu de div (print.html)

<div>
  <div>
    Do not print
  </div>
  <div id="printable">
    Print this div
  </div>
  <button ng-click="printDiv('printableArea');">Print Div</button>
</div>

Le contrôleur a le script suivant:

$scope.printDiv = function(divName) {
    var printContents = document.getElementById(divName).innerHTML;
    var originalContents = document.body.innerHTML;        
    document.body.innerHTML = printContents;
    window.print();
    document.body.innerHTML = originalContents;
}

Ce code imprime le div désiré mais il y a un problème. l'instruction document.body.innerHTML = originalContents; remplace le corps de l'application entière puisqu'il s'agit d'un SPA. Ainsi, lorsque je rafraîchis la page ou que je clique à nouveau sur le bouton Imprimer, tout le contenu de la page est effacé.

32
Priyatam Roy
$scope.printDiv = function(divName) {
  var printContents = document.getElementById(divName).innerHTML;
  var popupWin = window.open('', '_blank', 'width=300,height=300');
  popupWin.document.open();
  popupWin.document.write('<html><head><link rel="stylesheet" type="text/css" href="style.css" /></head><body onload="window.print()">' + printContents + '</body></html>');
  popupWin.document.close();
} 
88
Anand Natarajan

Deux fonctions conditionnelles sont nécessaires: une pour Google Chrome et une seconde pour les navigateurs restants.

$scope.printDiv = function (divName) {

    var printContents = document.getElementById(divName).innerHTML;
    var originalContents = document.body.innerHTML;      

    if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
        var popupWin = window.open('', '_blank', 'width=600,height=600,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no');
        popupWin.window.focus();
        popupWin.document.write('<!DOCTYPE html><html><head>' +
            '<link rel="stylesheet" type="text/css" href="style.css" />' +
            '</head><body onload="window.print()"><div class="reward-body">' + printContents + '</div></html>');
        popupWin.onbeforeunload = function (event) {
            popupWin.close();
            return '.\n';
        };
        popupWin.onabort = function (event) {
            popupWin.document.close();
            popupWin.close();
        }
    } else {
        var popupWin = window.open('', '_blank', 'width=800,height=600');
        popupWin.document.open();
        popupWin.document.write('<html><head><link rel="stylesheet" type="text/css" href="style.css" /></head><body onload="window.print()">' + printContents + '</html>');
        popupWin.document.close();
    }
    popupWin.document.close();

    return true;
}
10
Amit Jadli

Vous pouvez maintenant utiliser la bibliothèque appelée angular-print

7
TMichel

J'ai fait de cette façon:

$scope.printDiv = function (div) {
  var docHead = document.head.outerHTML;
  var printContents = document.getElementById(div).outerHTML;
  var winAttr = "location=yes, statusbar=no, menubar=no, titlebar=no, toolbar=no,dependent=no, width=865, height=600, resizable=yes, screenX=200, screenY=200, personalbar=no, scrollbars=yes";

  var newWin = window.open("", "_blank", winAttr);
  var writeDoc = newWin.document;
  writeDoc.open();
  writeDoc.write('<!doctype html><html>' + docHead + '<body onLoad="window.print()">' + printContents + '</body></html>');
  writeDoc.close();
  newWin.focus();
}
1
Azhar

C'est ce qui a fonctionné pour moi dans Chrome et Firefox! Cela ouvrira la petite fenêtre d’impression et la fermera automatiquement une fois que vous aurez cliqué sur Imprimer.

var printContents = document.getElementById('div-id-selector').innerHTML;
            var popupWin = window.open('', '_blank', 'width=800,height=800,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no,top=50');
            popupWin.window.focus();
            popupWin.document.open();
            popupWin.document.write('<!DOCTYPE html><html><head><title>TITLE OF THE PRINT OUT</title>' 
                                    +'<link rel="stylesheet" type="text/css" href="app/directory/file.css" />' 
                                    +'</head><body onload="window.print(); window.close();"><div>' 
                                    + printContents + '</div></html>');
            popupWin.document.close();
0
tyborg

D'accord, je pourrais avoir une approche même différente.

Je suis conscient que cela ne conviendra pas à tout le monde mais que, néanmoins, quelqu'un pourrait le trouver utile.

Pour ceux qui ne veulent pas créer une nouvelle fenêtre et qui, comme moi, s’inquiètent des styles CSS, c’est ce que j’ai trouvé:

J'ai enveloppé la vue de mon application dans un conteneur supplémentaire, qui est masqué lors de l'impression et un conteneur supplémentaire pour ce qui doit être imprimé est affiché lors de l'impression.

Exemple de travail ci-dessous:

var app = angular.module('myApp', []);
	app.controller('myCtrl', function($scope) {
  
    $scope.people = [{
      "id" : "000",
      "name" : "alfred"
    },
    {
      "id" : "020",
      "name" : "robert"
    },
    {
      "id" : "200",
      "name" : "me"
    }];

    $scope.isPrinting = false;
		$scope.printElement = {};
		
		$scope.printDiv = function(e)
		{
			console.log(e);
			$scope.printElement = e;
			
			$scope.isPrinting = true;
      
      //does not seem to work without toimeouts
			setTimeout(function(){
				window.print();
			},50);
			
			setTimeout(function(){
				$scope.isPrinting = false;
			},50);
			
			
		};
    
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp" ng-controller="myCtrl">

	<div ng-show="isPrinting">
		<p>Print me id: {{printElement.id}}</p>
    <p>Print me name: {{printElement.name}}</p>
	</div>
	
	<div ng-hide="isPrinting">
    <!-- your actual application code -->
    <div ng-repeat="person in people">
      <div ng-click="printDiv(person)">Print {{person.name}}</div>
    </div>
  </div>
  
  
</div>
	

Notez que je suis conscient du fait que ce n’est pas une solution élégante et présente plusieurs inconvénients, mais il présente également quelques avantages:

  • n'a pas besoin d'une fenêtre popup
  • garde le css intact
  • ne stocke pas votre page entière dans un var (pour une raison quelconque, vous ne voulez pas le faire)

Bon, qui que vous lisiez, passez une bonne journée et continuez à coder :)

MODIFIER:

Si cela vous convient, vous pouvez utiliser:

@media print  { .noprint  { display: none; } }
@media screen { .noscreen { visibility: hidden; position: absolute; } }

au lieu de booléens angulaires pour sélectionner votre contenu à imprimer ou non

MODIFIER:

Css de l'écran modifié car il apparaît cet affichage: aucun n'interrompt l'impression lors de la première impression après le chargement/l'actualisation d'une page.

visibilité: l'approche cachée semble fonctionner jusqu'à présent.

0
Kamil Wężyk