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:
make a query to pull the <style>
and <link>
elements from the top-level document
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