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

31
demandé sur Neeraj Rathod 2016-12-29 14:58:08

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();
}
58
répondu selem mn 2016-12-29 12:39:00

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.

11
répondu Farasi78 2018-07-10 16:45:55

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>
10
répondu Vikash Dahiya 2016-12-29 13:59:01

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.

1
répondu Kliment Ru 2017-11-13 06:27:40

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);
  }

}
0
répondu Dave Gööck 2018-05-24 18:50:06

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

0
répondu lenard-bernardo-ei 2018-10-08 06:35:51