visit
Unfortunately Angular doesn’t have an exposed method to compile an Angular component into an HTML string. But thanks to Angular’s ComponentFactoryResolver
, we can create a workaround for this. Using ComponentFactoryResolver
, we can dynamically render the required component into a template, and then we access the nativeElement.innerHTML
from componentRef
.
One thing to note here is we have used import { asyncScheduler } from 'rxjs';
for getting HTML with all the bindings. If we are not setting this scheduler, no data binding will be available in the parse HTML.
import {
Component,
ComponentFactory,
ComponentFactoryResolver,
ViewChild,
ViewContainerRef,
} from '@angular/core';
import { asyncScheduler } from 'rxjs';
import { PdfHtmlComponent } from './pdf-html.component';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
@ViewChild('pdfHtml', { read: ViewContainerRef }) container;
constructor(private resolver: ComponentFactoryResolver) {}
getPDFHtml() {
this.container.clear();
const factory: ComponentFactory<any> =
this.resolver.resolveComponentFactory(PdfHtmlComponent);
const componentRef = this.container.createComponent(factory);
componentRef.instance.title = 'Injected Title';
asyncScheduler.schedule(() => {
const htmlString = componentRef.location.nativeElement.innerHTML;
componentRef.destroy();
console.log('HTML STRING:', htmlString);
});
}
}
<button (click)="getPDFHtml()">CLICK TO GET COMPONENT HTML</button>
<p>Output is in the console</p>
<div [hidden]="true">
<template #pdfHtml></template>
</div>
import { Component } from '@angular/core';
@Component({
selector: 'pdf-html',
templateUrl: './pdf-html.component.html',
})
export class PdfHtmlComponent {
title: string = 'Default Title';
STYLES: any = {
MAIN_CONTAINER: 'background:red;',
ITEM_BOX: 'color:red;',
};
}
<h2>Title: {{ title }}</h2>
<table style="{{ STYLES.MAIN_CONTAINER }}">
<tr style="{{ STYLES.ITEM_BOX }}">
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr style="{{ STYLES.ITEM_BOX }}">
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr style="{{ STYLES.ITEM_BOX }}">
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr style="{{ STYLES.ITEM_BOX }}">
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
</table>
You can see the demo here