Introduces a download button in the reservation success component to allow users to download their reservation code as a text file. Adds utility methods in PdfService for downloading text and JSON files, and integrates the new download functionality into the component.
142 lines
4.3 KiB
TypeScript
142 lines
4.3 KiB
TypeScript
import { Injectable, ComponentRef, ViewContainerRef, ApplicationRef, createComponent, EnvironmentInjector, inject, signal } from '@angular/core';
|
|
import html2canvas from 'html2canvas';
|
|
import jsPDF from 'jspdf';
|
|
import { Eintrittskarte } from '@infinimotion/model-frontend';
|
|
|
|
@Injectable({
|
|
providedIn: 'root',
|
|
})
|
|
export class PdfService {
|
|
private ticketsGreatedSignal = signal(0);
|
|
private totalTicketsSignal = signal(0);
|
|
|
|
readonly ticketsGreated = this.ticketsGreatedSignal.asReadonly();
|
|
readonly totalTickets = this.totalTicketsSignal.asReadonly();
|
|
|
|
appRef = inject(ApplicationRef);
|
|
injector = inject(EnvironmentInjector);
|
|
|
|
async genTicket(tickets: Eintrittskarte[], ticketComponent: any): Promise<void> {
|
|
if (tickets.length === 0) {
|
|
throw new Error('Keine Tickets zum Generieren vorhanden');
|
|
}
|
|
|
|
this.ticketsGreatedSignal.set(0)
|
|
this.totalTicketsSignal.set(tickets.length)
|
|
|
|
// Container für temporäres Rendering erstellen
|
|
const container = document.createElement('div');
|
|
container.style.position = 'fixed';
|
|
container.style.left = '-9999px';
|
|
container.style.top = '0';
|
|
document.body.appendChild(container);
|
|
|
|
const componentRefs: ComponentRef<any>[] = [];
|
|
|
|
try {
|
|
// Ticket-Format: 210mm x 99mm
|
|
const ticketWidthMM = 210;
|
|
const ticketHeightMM = 99;
|
|
|
|
const pdf = new jsPDF({
|
|
orientation: 'landscape',
|
|
unit: 'mm',
|
|
format: [ticketWidthMM, ticketHeightMM]
|
|
});
|
|
|
|
for (let i = 0; i < tickets.length; i++) {
|
|
const ticket = tickets[i];
|
|
|
|
// Komponente dynamisch erstellen
|
|
const componentRef = createComponent(ticketComponent, {
|
|
environmentInjector: this.injector
|
|
});
|
|
|
|
// Ticket-Daten an die Komponente übergeben
|
|
(componentRef.instance as any).ticket = ticket;
|
|
|
|
// Komponente ins DOM einfügen
|
|
this.appRef.attachView(componentRef.hostView);
|
|
container.appendChild(componentRef.location.nativeElement);
|
|
componentRefs.push(componentRef);
|
|
|
|
// Change Detection triggern
|
|
componentRef.changeDetectorRef.detectChanges();
|
|
|
|
// Kurz warten, damit alles gerendert ist
|
|
await new Promise(requestAnimationFrame);
|
|
|
|
// HTML zu Canvas konvertieren
|
|
const canvas = await html2canvas(componentRef.location.nativeElement, {
|
|
scale: 2,
|
|
backgroundColor: '#ffffff',
|
|
logging: false,
|
|
useCORS: true
|
|
});
|
|
|
|
const imgData = canvas.toDataURL('image/png');
|
|
|
|
if (i > 0) {
|
|
pdf.addPage([ticketWidthMM, ticketHeightMM], 'landscape');
|
|
}
|
|
|
|
// Bild ins PDF einfügen
|
|
pdf.addImage(imgData, 'PNG', 0, 0, ticketWidthMM, ticketHeightMM);
|
|
|
|
this.ticketsGreatedSignal.set(this.ticketsGreatedSignal() + 1)
|
|
}
|
|
|
|
const fileName = this.generateFileName(tickets);
|
|
pdf.save(fileName);
|
|
|
|
} catch (error) {
|
|
console.error('Fehler beim Generieren des PDFs:', error);
|
|
throw new Error('Das PDF konnte nicht erstellt werden. Bitte versuche es erneut.');
|
|
} finally {
|
|
componentRefs.forEach(ref => {
|
|
this.appRef.detachView(ref.hostView);
|
|
ref.destroy();
|
|
});
|
|
document.body.removeChild(container);
|
|
}
|
|
}
|
|
|
|
private generateFileName(tickets: Eintrittskarte[]): string {
|
|
const orderCode = tickets[0].order.code;
|
|
const timestamp = new Date().getTime();
|
|
|
|
return `Ticket_${orderCode}_${timestamp}.pdf`;
|
|
}
|
|
|
|
downloadTextFile(content: string, filename: string = 'textdatei.txt'): void {
|
|
|
|
const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
|
|
const url = window.URL.createObjectURL(blob);
|
|
|
|
const link = document.createElement('a');
|
|
link.href = url;
|
|
link.download = filename;
|
|
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
|
|
window.URL.revokeObjectURL(url);
|
|
}
|
|
|
|
downloadJsonFile(data: any, filename: string = 'data.json'): void {
|
|
const content = JSON.stringify(data, null, 2);
|
|
const blob = new Blob([content], { type: 'application/json' });
|
|
const url = window.URL.createObjectURL(blob);
|
|
|
|
const link = document.createElement('a');
|
|
link.href = url;
|
|
link.download = filename;
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
window.URL.revokeObjectURL(url);
|
|
}
|
|
}
|
|
|