Print Html template in Angular 2 (ng-print in Angular 2)

EDIT: updated the snippets for a more generic approach

Just as an extension to the accepted answer,

For getting the existing styles to preserve the look 'n feel of the targeted component, you can:

  1. make a query to pull the <style> and <link> elements from the top-level document

  2. inject it into the HTML string.

To grab a HTML tag:

private getTagsHtml(tagName: keyof HTMLElementTagNameMap): string
{
    const htmlStr: string[] = [];
    const elements = document.getElementsByTagName(tagName);
    for (let idx = 0; idx < elements.length; idx++)
    {
        htmlStr.push(elements[idx].outerHTML);
    }

    return htmlStr.join('\r\n');
}

Then in the existing snippet:

const printContents = document.getElementById('print-section').innerHTML;
const stylesHtml = this.getTagsHtml('style');
const linksHtml = this.getTagsHtml('link');

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>
            ${linksHtml}
            ${stylesHtml}
            ^^^^^^^^^^^^^ add them as usual to the head
        </head>
        <body onload="window.print(); window.close()">
            ${printContents}
        </body>
    </html>
    `
);
popupWin.document.close();

Now using existing styles (Angular components create a minted style for itself), as well as existing style frameworks (e.g. Bootstrap, MaterialDesign, Bulma) it should look like a snippet of the existing screen


you can do like this in angular 2

in ts file

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

 }

in 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>

In case anyone else comes across this problem, if you have already laid the page out, I would recommend using media queries to set up your print page. You can then simply attach a print function to your html button and in your component call window.print();

component.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>

component.ts:

onPrint(){
    window.print();
}

component.css:

@media print{
  .doNotPrint{display:none !important;}
}

You can optionally also add other elements / sections you do not wish to print in the media query.

You can change the document margins and all in the print query as well, which makes it quite powerful. There are many articles online. Here is one that seems comprehensive: https://www.sitepoint.com/create-a-customized-print-stylesheet-in-minutes/ It also means you don't have to create a separate script to create a 'print version' of the page or use lots of javascript.


That's how I've done it in angular2 (it is similar to that plunkered solution) In your HTML file:

<div id="print-section">
  // your html stuff that you want to print
</div>
<button (click)="print()">print</button>

and in your TS file :

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

UPDATE:

You can also shortcut the path and use merely ngx-print library for less inconsistent coding (mixing JS and TS) and more out-of-the-box controllable and secured printing cases.