HTMLテンプレートをangularで印刷したい。これについて調べたところ、angularjs 1で解決策が得られた Angularjs 1でHTMLテンプレートを印刷
任意の提案をいただければ幸いです
それは私がangular2でそれをやった方法です(それはplunkeredソリューションに似ています)あなたのHTMLファイルで:
<div id="print-section">
// your html stuff that you want to print
</div>
<button (click)="print()">print</button>
そしてあなたの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();
}
また、パスをショートカットして、 ngx-print ライブラリを使用することで、一貫性のないコーディング(JSとTSの混合)およびすぐに使用可能な制御可能安全な印刷ケース
他の誰かがこの問題に遭遇した場合、すでにページをレイアウトしているなら、メディアクエリを使用して印刷ページを設定することをお勧めします。次に、HTMLボタンに印刷関数を添付し、コンポーネントで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;}
}
オプションで、メディアクエリに印刷したくない他の要素/セクションを追加することもできます。
文書の余白を変更したり、印刷クエリのすべてを変更したりすることもできるため、非常に強力です。オンラインで多くの記事があります。包括的なように見えるものは次のとおりです。 https://www.sitepoint.com/create-a-customized-print-stylesheet-in-minutes/ また、個別に作成する必要がないことも意味しますページの「印刷バージョン」を作成するスクリプト、または多くのjavascriptを使用するスクリプト。
angular 2でこのようにすることができます
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();
}
}
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>
編集:より一般的なアプローチのためにスニペットを更新しました
受け入れられた答えの延長として、
既存のスタイルを取得して、ターゲットコンポーネントのルックアンドフィールを保持するには、次のことができます。
最上位ドキュメントから<style>
および<link>
要素を取得するクエリを作成します
hTML文字列に挿入します。
HTMLタグを取得するには:
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');
}
次に、既存のスニペットで:
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();
現在、既存のスタイル(Angularコンポーネントはそれ自体にミントスタイルを作成します)と既存のスタイルフレームワーク(Bootstrap、MaterialDesign、Bulmaなど)を使用して、既存の画面のスニペットのように見えるはずです
印刷サービス
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();
}
}
印刷したい項目
@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);
}
}
最良の選択ではありませんが、機能します。
私は同じ問題に遭遇し、これを行う別の方法を見つけました。比較的小さなアプリケーションであったため、私の場合はうまくいきました。
最初に、ユーザーは印刷する必要のあるコンポーネントのボタンをクリックします。これにより、アプリコンポーネントからアクセスできるフラグが設定されます。そのようです
.htmlファイル
<button mat-button (click)="printMode()">Print Preview</button>
.tsファイル
printMode() {
this.utilities.printMode = true;
}
アプリコンポーネントのhtmlでは、ルーターアウトレット以外のすべてを非表示にします。以下のようなもの
<div class="container">
<app-header *ngIf="!utilities.printMode"></app-header>
<mat-sidenav-container>
<mat-sidenav *ngIf="=!utilities.printMode">
<app-sidebar></app-sidebar>
</mat-sidenav>
<mat-sidenav-content>
<router-outlet></router-outlet>
</mat-sidenav-content>
</mat-sidenav-container>
</div>
同様のngIf条件で、コンポーネントのhtmlテンプレートを調整して、printModeでのみ表示または非表示にすることもできます。そのため、ユーザーは、印刷プレビューをクリックしたときに印刷する必要があるものだけを見ることができます。
次のコードを使用して、単に印刷するか、通常モードに戻ることができます。
.htmlファイル
<button mat-button class="doNotPrint" (click)="print()">Print</button>
<button mat-button class="doNotPrint" (click)="endPrint()">Close</button>
.tsファイル
print() {
window.print();
}
endPrint() {
this.utilities.printMode = false;
}
.cssファイル(印刷ボタンと閉じるボタンが印刷されないようにするため)
@media print{
.doNotPrint{display:none !important;}
}
私のスタイルに悩まされることなくこれを解決するために見つけた最良のオプションは、印刷出力に別のルートを使用し、このルートをiframeにロードすることでした。
周囲のコンポーネントはタブページとして表示されます。
@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;
}
}
Iframeは、アプリで印刷コンポーネントをレンダリングする印刷ルートをロードするだけです。このページでは、ビューが完全に初期化された後に印刷がトリガーされる場合があります。別の方法は、window.frames["printpage"].print();
によってiframeの印刷をトリガーする親コンポーネントの印刷ボタンです。
@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);
}
}
ウィンドウをTypeScript変数に割り当て、次にその上でprintメソッドを呼び出す最短のソリューション
テンプレートファイル内
<button ... (click)="window.print()" ...>Submit</button>
そして、TypeScriptファイルで
window: any;
constructor() {
this.window = window;
}
通常、Windowsアプリケーションには組み込みの印刷機能が付属していますが、Webアプリケーションの場合は、PDFファイルを生成するだけです。
私が見つけた最も簡単な方法は、PDFMake(www.pdfmake.org)を使用してPDfファイルを生成することです。次に、生成されたPDFファイルを開くかダウンロードするかをユーザーに選択できます。