Imprimer le modèle Html dans Angular 2 (ng-imprimer dans Angular 2)
Je veux imprimer un modèle HTML dans angular 2. J'avais exploré à ce sujet j'ai obtenu une solution dans angularjs 1 imprimer le modèle Html dans Angularjs 1
Toute suggestion serait appréciée
6 réponses
Voilà comment je l'ai fait dans angular2 (c'est similaire à celleplunkered solution) dans votre fichier HTML:
<div id="print-section">
// your html stuff that you want to print
</div>
<button (click)="print()">print</button>
Et dans votre fichier TS:
print(): void {
let printContents, popupWin;
printContents = document.getElementById('print-section').innerHTML;
popupWin = window.open('', '_blank', 'top=0,left=0,height=100%,width=auto');
popupWin.document.open();
popupWin.document.write(`
<html>
<head>
<title>Print tab</title>
<style>
//........Customized style.......
</style>
</head>
<body onload="window.print();window.close()">${printContents}</body>
</html>`
);
popupWin.document.close();
}
Dans le cas où quelqu'un d'autre rencontre ce problème, si vous avez déjà posé la page, je vous recommande d'utiliser des requêtes média pour configurer votre page d'impression. Vous pouvez ensuite simplement attacher une fonction d'impression à votre bouton html et dans votre fenêtre d'appel de Composant.imprimer ();
Composant.html:
<div class="doNotPrint">
Header is here.
</div>
<div>
all my beautiful print-related material is here.
</div>
<div class="doNotPrint">
my footer is here.
<button (click)="onPrint()">Print</button>
</div>
Composant.ts:
onPrint(){
window.print();
}
Composant.css:
@media print{
.doNotPrint{display:none !important;}
}
Vous pouvez éventuellement ajouter d'autres éléments / sections que vous ne souhaitez pas imprimer dans la requête média.
Vous pouvez modifiez les marges du document et tout dans la requête d'impression, ce qui le rend assez puissant. Il existe de nombreux articles en ligne. En voici un qui semble complet: https://www.sitepoint.com/create-a-customized-print-stylesheet-in-minutes/{[15] } cela signifie également que vous n'avez pas besoin de créer un script séparé pour créer une "version imprimée" de la page ou utiliser beaucoup de javascript.
Vous pouvez faire comme ceci angulaire 2
Dans le fichier ts
export class Component{
constructor(){
}
printToCart(printSectionId: string){
let popupWinindow
let innerContents = document.getElementById(printSectionId).innerHTML;
popupWinindow = window.open('', '_blank', 'width=600,height=700,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no');
popupWinindow.document.open();
popupWinindow.document.write('<html><head><link rel="stylesheet" type="text/css" href="style.css" /></head><body onload="window.print()">' + innerContents + '</html>');
popupWinindow.document.close();
}
}
En html
<div id="printSectionId" >
<div>
<h1>AngularJS Print html templates</h1>
<form novalidate>
First Name:
<input type="text" class="tb8">
<br>
<br> Last Name:
<input type="text" class="tb8">
<br>
<br>
<button class="button">Submit</button>
<button (click)="printToCart('printSectionId')" class="button">Print</button>
</form>
</div>
<div>
<br/>
</div>
</div>
Service D'impression
import { Injectable } from '@angular/core';
@Injectable()
export class PrintingService {
public print(printEl: HTMLElement) {
let printContainer: HTMLElement = document.querySelector('#print-container');
if (!printContainer) {
printContainer = document.createElement('div');
printContainer.id = 'print-container';
}
printContainer.innerHTML = '';
let elementCopy = printEl.cloneNode(true);
printContainer.appendChild(elementCopy);
document.body.appendChild(printContainer);
window.print();
}
}
Composant que je veux imprimer
@Component({
selector: 'app-component',
templateUrl: './component.component.html',
styleUrls: ['./component.component.css'],
encapsulation: ViewEncapsulation.None
})
export class MyComponent {
@ViewChild('printEl') printEl: ElementRef;
constructor(private printingService: PrintingService) {}
public print(): void {
this.printingService.print(this.printEl.nativeElement);
}
}
Pas le meilleur choix, mais fonctionne.
La meilleure option que j'ai trouvée pour résoudre ce problème sans avoir de problèmes avec mes styles était d'utiliser une route séparée pour ma sortie imprimée et de charger cette route dans un iframe.
Mon composant environnant est affiché sous la forme d'une page à onglets.
@Component({
template: '<iframe id="printpage" name="printpage" *ngIf="printSrc" [src]="printSrc"></iframe>',
styleUrls: [ 'previewTab.scss' ]
})
export class PreviewTabPage {
printSrc: SafeUrl;
constructor(
private navParams: NavParams,
private sanitizer: DomSanitizer,
) {
// item to print is passed as url parameter
const itemId = navParams.get('itemId');
// set print page source for iframe in template
this.printSrc = this.sanitizer.bypassSecurityTrustResourceUrl(this.getAbsoluteUrl(itemId));
}
getAbsoluteUrl(itemId: string): string {
// some code to generate an absolute url for your item
return itemUrl;
}
}
L'iframe charge simplement la route d'impression qui rend un composant d'impression dans l'application. Dans cette page, l'impression peut être déclenchée après l'initialisation complète de la vue. Une autre façon pourrait être un bouton d'impression sur le composant parent qui déclenche l'impression sur l'iframe par window.frames["printpage"].print();
.
@Component({
templateUrl: './print.html',
styleUrls: [ 'print.scss' ]
})
export class PrintPage implements AfterViewInit {
constructor() {}
ngAfterViewInit() {
// wait some time, so all images or other async data are loaded / rendered.
// print could be triggered after button press in the parent component as well.
setTimeout(() => {
// print current iframe
window.print();
}, 2000);
}
}
Tout comme une extension à la réponse acceptée,
Pour obtenir les styles existants dont vous avez besoin pour préserver l'apparence du composant ciblé, vous pouvez créer une requête pour extraire les éléments <style>
du document de niveau supérieur et l'injecter dans la chaîne HTML.
const getStylesHtml = (document: Document): string =>
{
const styles: string[] = [];
const styleElements = document.getElementsByTagName('style');
for (let idx = 0; idx < styleElements.length; idx++)
{
styles.push(styleElements[idx].outerHTML);
^^^^^^^^^ whole element, not just contents
}
return styles.join('\r\n');
};
Puis dans dans l'extrait existant:
const printContents = document.getElementById('print-section').innerHTML;
const popupWin = window.open('', '_blank', 'top=0,left=0,height=100%,width=auto');
popupWin.document.open();
popupWin.document.write(`
<html>
<head>
<title>Print tab</title>
${getStylesHtml(document)}
^^^^^^^^^^ pass reference to the document
</head>
<body onload="window.print(); window.close()">
${printContents}
</body>
</html>
`
);
popupWin.document.close();
Maintenant, en utilisant des styles existants (Les composants angulaires créent un style frappé pour lui-même), ainsi que des cadres de style existants (par exemple Bootstrap, MaterialDesign, Bulma) il devrait ressembler à un extrait de l'écran existant