在 Angular 中隐藏 PDF 内容设计组件

问题描述 投票:0回答:1

我有两个组件。计费组件(用户输入项目详细信息)和计费组件(设计 PDF 页面并生成 pdf)。

(billing.ts)中的项目详细信息通过服务(pdfcontent.service.ts)传递到账单组件(billpage.ts)。

下面我分享了屏幕截图。除了一个重大问题外,一切都运行良好。在这里,当我提交按钮时,pdf 是从 billpage 组件生成的。但 pdf 页面的设计(以黄色方块突出显示)出现在计费页面中。 但我不需要在视图中显示这一点。我执行以下步骤来避免,但没有一个给出好的结果。

  1. <app-billpage style="display:none"></app-billpage>
    显示无属性时不会生成 PDF。
  2. <app-billpage style="visibility:hidden"></app-billpage>
    生成空 pdf。
  3. 已删除
    <app-billpage></app-billpage>
    未生成 pdf。

billing component

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 pdf jspdf
1个回答
0
投票

您可以在组件内创建额外的变量来隐藏模板,直到下载完成,尽管您可能会看到内容出现一小段时间。

可能需要使用 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 并打印。

© www.soinside.com 2019 - 2024. All rights reserved.