我有两个组件。计费组件(用户输入项目详细信息)和计费组件(设计 PDF 页面并生成 pdf)。
(billing.ts)中的项目详细信息通过服务(pdfcontent.service.ts)传递到账单组件(billpage.ts)。
下面我分享了屏幕截图。除了一个重大问题外,一切都运行良好。在这里,当我提交按钮时,pdf 是从 billpage 组件生成的。但 pdf 页面的设计(以黄色方块突出显示)出现在计费页面中。 但我不需要在视图中显示这一点。我执行以下步骤来避免,但没有一个给出好的结果。
<app-billpage style="display:none"></app-billpage>
显示无属性时不会生成 PDF。<app-billpage style="visibility:hidden"></app-billpage>
生成空 pdf。<app-billpage></app-billpage>
未生成 pdf。billing.component.html
<form [formGroup]="productFormarray">
.....
....
...
</form>
<app-billpage></app-billpage>
计费.组件.ts
onSubmit() {
this.billcontent=this.productFormarray.value;
this.pdfService.updatePdfContent(this.billcontent);
}
pdfcontent.services.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class PdfcontentService {
constructor() { }
public pdfContentSource = new BehaviorSubject<any>("");
pdfContent$ = this.pdfContentSource.asObservable();
updatePdfContent(content: any) {
this.pdfContentSource.next(content);
}
}
billpage.component.html
<div id="billpagecontent" class="p-4">
<p>Customer Name: {{billpagecontent.customername}}</p>
<p>Contact Number: </p>
<p>Bill No</p>
<table class="table" style="margin-top: 20px; width:fit-content;">
<thead>
<tr>
<td style="width:40%">
Product Name
</td>
<td style="width:15%; text-align: right;">
Quantity
</td>
<td style="width:15%; text-align: right;">
Price
</td>
<td style="width:15%; text-align: right;">
Gst
</td>
</tr>
</thead>
<tr *ngFor="let product of billpagecontent.productdetails">
<td>{{product.productname}}</td>
<td style="text-align: right;">{{product.quantit}}</td>
<td style="text-align: right;">{{product.price}}</td>
<td style="text-align: right;">{{product.gst}}</td>
</tr>
<tr>
<td></td>
<td style="text-align: right;"><b>Total</b></td>
<td style="text-align: right;">{{billpagecontent.totalprice}}</td>
<td style="text-align: right;">{{billpagecontent.totalgst}}</td>
</tr>
<tr>
<td></td>
<td style="text-align: right;"><b>Total Bill</b></td>
<td style="text-align: right;">{{billpagecontent.overalltotal}}</td>
<td style="text-align: right;"></td>
</tr>
</table>
</div>
billpage.component.ts
import { Component, OnInit } from '@angular/core';
import jsPDF from 'jspdf';
import html2canvas from 'html2canvas';
import { PdfcontentService } from '../services/pdfcontent.service';
@Component({
selector: 'app-billpage',
templateUrl: './billpage.component.html',
styleUrls: ['./billpage.component.css']
})
export class BillpageComponent implements OnInit {
billpagecontent: any = {};
constructor(public pdfService: PdfcontentService) {
}
ngOnInit(): void {
this.pdfService.pdfContent$.subscribe(content => {
if (content) {
this.billpagecontent = content;
let pdfcontent = document.getElementById('billpagecontent');
setTimeout(() => {
this.convetToPDF(pdfcontent);
}, 3000);
}
});
}
public convetToPDF(bcontent: any) {
var data = bcontent as HTMLCanvasElement;
html2canvas(data).then(canvas => {
// Few necessary setting options
var imgWidth = 208;
var pageHeight = 295;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
const contentDataURL = canvas.toDataURL('image/png')
let pdf = new jsPDF('p', 'mm', 'a4'); // A4 size page of PDF
var position = 0;
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight)
pdf.save('new-file.pdf'); // Generated PDF
});
}
}
请有人帮忙解决这个问题。 如何启动另一个组件而不放置该组件的模板。 (
<app-billpage></app-billpage>
)
您可以在组件内创建额外的变量来隐藏模板,直到下载完成,尽管您可能会看到内容出现一小段时间。
可能需要使用 Angular detectorChange 等待 ngIf 加载后再下载。
<div id="billpagecontent" class="p-4" *ngIf="showContent">
<p>Customer Name: {{billpagecontent.customername}}</p>
<p>Contact Number: </p>
<p>Bill No</p>
<table class="table" style="margin-top: 20px; width:fit-content;">
<thead>
<tr>
<td style="width:40%">
Product Name
</td>
<td style="width:15%; text-align: right;">
Quantity
</td>
<td style="width:15%; text-align: right;">
Price
</td>
<td style="width:15%; text-align: right;">
Gst
</td>
</tr>
</thead>
<tr *ngFor="let product of billpagecontent.productdetails">
<td>{{product.productname}}</td>
<td style="text-align: right;">{{product.quantit}}</td>
<td style="text-align: right;">{{product.price}}</td>
<td style="text-align: right;">{{product.gst}}</td>
</tr>
<tr>
<td></td>
<td style="text-align: right;"><b>Total</b></td>
<td style="text-align: right;">{{billpagecontent.totalprice}}</td>
<td style="text-align: right;">{{billpagecontent.totalgst}}</td>
</tr>
<tr>
<td></td>
<td style="text-align: right;"><b>Total Bill</b></td>
<td style="text-align: right;">{{billpagecontent.overalltotal}}</td>
<td style="text-align: right;"></td>
</tr>
</table>
</div>
billpage.component.ts
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import jsPDF from 'jspdf';
import html2canvas from 'html2canvas';
import { PdfcontentService } from '../services/pdfcontent.service';
@Component({
selector: 'app-billpage',
templateUrl: './billpage.component.html',
styleUrls: ['./billpage.component.css']
})
export class BillpageComponent implements OnInit {
billpagecontent: any = {};
showContent: boolean = false;
constructor(public pdfService: PdfcontentService, private detectorChange: ChangeDetectorRef) {
}
ngOnInit(): void {
this.pdfService.pdfContent$.subscribe(content => {
if (content) {
this.billpagecontent = content;
let pdfcontent = document.getElementById('billpagecontent');
setTimeout(() => {
this.convetToPDF(pdfcontent);
}, 3000);
}
});
}
public convetToPDF(bcontent: any) {
showContent = true;
this.detectorChange.detectChanges();
var data = bcontent as HTMLCanvasElement;
html2canvas(data).then(canvas => {
// Few necessary setting options
var imgWidth = 208;
var pageHeight = 295;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
const contentDataURL = canvas.toDataURL('image/png')
let pdf = new jsPDF('p', 'mm', 'a4'); // A4 size page of PDF
var position = 0;
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight)
pdf.save('new-file.pdf'); // Generated PDF
showContent = false;
});
}
}
如果您想更好地控制内容打印端及其外观,也许您可以创建一个调用
window.print()
的按钮。通过此策略,您可以使用 @media print
CSS 媒体查询覆盖 PDF 的 CSS 样式。此外,用户可以使用相同的打印对话框保存为 PDF 并打印。