<link rel="stylesheet" href="styles-3GBANQL6.css">
← Zurück zum Blog

Angular

Angular-Direktive zur Umwandlung von HTML in PDF

Angular-Direktive zur Umwandlung von HTML in PDF

Bei der Entwicklung von Anwendungen, insbesondere in Angular, kann es vorkommen, dass Sie Nutzern die Möglichkeit geben müssen, Bereiche Ihrer Website oder Anwendung als PDFs herunterzuladen. Sei es eine Rechnung, ein Bericht oder dynamische Inhalte – eine nahtlose Methode, HTML in PDF-Dateien zu konvertieren, ist äußerst wertvoll. In diesem Blog werde ich die Erstellung einer benutzerdefinierten Direktive durchgehen, die HTML-Elemente in PDF umwandeln kann, und dabei jsPDF und html2canvas verwendet.

Warum eine benutzerdefinierte Direktive verwenden?

Direktiven in Angular ermöglichen es Ihnen, das Verhalten von DOM-Elementen zu erweitern. In diesem Szenario lauscht unsere Direktive auf ein Klick-Ereignis und erzeugt eine PDF-Version des HTML-Elements, auf das sie angewendet wird. So bleibt die PDF-Erzeugungslogik von der Geschäftslogik der Komponente getrennt, was den Code sauberer und modularer macht.

Voraussetzungen

Um diesem Tutorial zu folgen, sollten Sie ein grundlegendes Verständnis von Angular haben und wissen, wie man mit Direktiven arbeitet. Wir verwenden die folgenden externen Bibliotheken:

  • jsPDF: Eine Bibliothek zur Erstellung von PDF-Dokumenten in JavaScript.
  • html2canvas: Eine Bibliothek, die es ermöglicht, "Screenshots" von HTML-Elementen zu machen und sie als Bilder auszugeben.

Sie können diese Abhängigkeiten mit npm installieren:

npm install jspdf html2canvas --save

Die HtmlToPdfDirective-Implementierung

Sehen wir uns die Implementierung der HtmlToPdfDirective an.


import { ChangeDetectorRef, Directive, HostListener, inject, Input } from '@angular/core';
import { jsPDF } from "jspdf";
import html2canvas from 'html2canvas';

@Directive({
    selector: '[tfHtmlToPdf]',
    standalone: true,
})
export class HtmlToPdfDirective {
    @Input() fileName!:string;
    @Input() set tfHtmlToPdf(templateRef: HTMLDivElement) {
        this._templateRef = templateRef;
    }
    private _templateRef!: HTMLDivElement;

    constructor(private changeDetectorRef: ChangeDetectorRef) {
    }

    @HostListener('click', [ '$event' ])
    onClick(event: Event) {
        event.preventDefault();
        event.stopPropagation();

        // Löst die Change Detection aus, bevor das PDF generiert wird,
        // um sicherzustellen, dass alle Änderungen bei der
        // PDF-Erstellung reflektiert werden (z. B. Sprachänderungen)
        this.changeDetectorRef.detectChanges();

        this.generatePdf();
    }

    private generatePdf() {
        html2canvas(this._templateRef).then(canvas => {
            const imgData = canvas.toDataURL("image/jpeg", 1.0);
            const doc = new jsPDF('p', 'px', [ canvas.width, canvas.height ]);
            doc.addImage(imgData, 'JPEG', 0, 0, canvas.width, canvas.height);
            doc.save(this.fileName);
        });
    }
}

Schritt-für-Schritt-Erklärung

  1. Directive Decorator (@Directive): Der @Directive-Dekorator gibt an, dass diese Klasse eine Angular-Direktive ist. Die selector-Eigenschaft definiert die benutzerdefinierte Direktive als tfHtmlToPdf, die im Komponententemplate verwendet wird.
  2. @Input-Dekoratoren:
    • @Input() fileName: Dieser Input gibt den Namen der PDF-Datei an, die generiert wird, wenn die Direktive ausgelöst wird.
    • @Input() set tfHtmlToPdf(templateRef: HTMLDivElement): Dieser Input ermöglicht es Ihnen, das HTML-Element (als Referenz) zu übergeben, das in ein PDF konvertiert werden soll.
  3. Change Detection: Wir injizieren ChangeDetectorRef in den Konstruktor. Dieser Dienst ermöglicht es uns, die Change Detection von Angular manuell auszulösen, um sicherzustellen, dass alle Inhaltsänderungen reflektiert werden, bevor das PDF generiert wird.
  4. @HostListener: Der @HostListener-Dekorator hört auf das 'click'-Ereignis. Wenn das HTML-Element, auf das diese Direktive angewendet wird, angeklickt wird, löst es die Methode onClick() aus. Dies stellt sicher, dass Nutzer das PDF durch Klicken auf das entsprechende UI-Element erzeugen können.
  5. PDF-Generierungslogik: Die Methode generatePdf() übernimmt die Hauptlogik:
    • Zuerst konvertiert html2canvas das Ziel-HTML-Element in eine Leinwand, die dann wie ein Bild bearbeitet werden kann.
    • Die Leinwand wird mit toDataURL() in ein JPEG-Bild konvertiert.
    • jsPDF erstellt dann ein neues PDF-Dokument und fügt das Bild hinzu.
    • Schließlich wird das generierte PDF mit dem angegebenen fileName heruntergeladen.

Wie verwendet man die Direktive?

Die Verwendung dieser Direktive ist einfach. Sie können sie auf jedes HTML-Element (wie ein div) anwenden und das Ziel-Element angeben, das in ein PDF umgewandelt werden soll.

Hier ist ein Beispiel:


<div id="content" #contentRef>
    <h1>This is your content</h1>
    <p>This content will be exported as PDF when you click the button.</p>
</div>

<button [tfHtmlToPdf]="contentRef" fileName="my-content.pdf">
    Download as PDF
</button>
    

In diesem Beispiel:

  • Die contentRef-Referenz zeigt auf das div-Element, das den Inhalt enthält.
  • Die tfHtmlToPdf-Direktive wird auf die Schaltfläche angewendet und mit contentRef verknüpft.
  • Durch Klicken auf die Schaltfläche wird das PDF mit dem Dateinamen mein-inhalt.pdf heruntergeladen.

Wichtige Überlegungen

  • Rendering-Qualität: Während html2canvas gute Arbeit bei der Erfassung der Inhalte leistet, hängt die Qualität des PDFs von der Auflösung der Leinwand und der Komplexität des HTML ab, das erfasst wird.
  • Kompatibilität über verschiedene Browser: Stellen Sie sicher, dass html2canvas und jsPDF in Ihren Zielbrowsern gut funktionieren, da es möglicherweise leichte Unterschiede bei der Darstellung gibt.
  • Große Inhalte: Für größere HTML-Inhalte müssen Sie möglicherweise die jsPDF-Einstellungen anpassen, um Inhalte, die mehrere Seiten umfassen, korrekt zu verarbeiten.

Fazit

Mit dieser einfachen Direktive können wir beliebige HTML-Inhalte in einer Angular-Anwendung leicht als PDF exportieren. Direktiven wie diese machen unseren Code modular, wiederverwendbar und sauber. Ob für Rechnungen, Berichte oder das Erfassen dynamischer Inhalte – dieser Ansatz ist leistungsstark und leicht in Ihr Projekt zu integrieren.

Viel Spaß beim Programmieren!

LASSEN SIE UNS ETWAS NEUES BAUEN

Aus Ihrer Idee kann die nächste gute Softwarelösung entstehen.

Erzählen Sie uns, was Sie entwickeln, verbessern oder neu denken möchten.

Projekt besprechen