Erweiterungen
This commit is contained in:
@@ -2,7 +2,9 @@ package de.assecutor.votianlt.pages.view;
|
||||
|
||||
import com.vaadin.flow.component.button.Button;
|
||||
import com.vaadin.flow.component.html.H2;
|
||||
import com.vaadin.flow.component.html.IFrame;
|
||||
import com.vaadin.flow.component.notification.Notification;
|
||||
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||
import com.vaadin.flow.router.PageTitle;
|
||||
import com.vaadin.flow.router.Route;
|
||||
@@ -19,6 +21,7 @@ import java.io.ByteArrayInputStream;
|
||||
@RolesAllowed("ADMIN")
|
||||
public class PdfTestView extends VerticalLayout {
|
||||
private final SystemInvoiceService systemInvoiceService;
|
||||
private IFrame pdfViewer;
|
||||
|
||||
public PdfTestView(SystemInvoiceService systemInvoiceService) {
|
||||
this.systemInvoiceService = systemInvoiceService;
|
||||
@@ -34,7 +37,29 @@ public class PdfTestView extends VerticalLayout {
|
||||
Button generatePdfButton = new Button("Test-Rechnung PDF generieren");
|
||||
generatePdfButton.addClickListener(e -> generateTestPdf());
|
||||
|
||||
add(generatePdfButton);
|
||||
Button generateHtmlPdfButton = new Button("PDF aus vltInvoice.html generieren");
|
||||
generateHtmlPdfButton.addClickListener(e -> generateHtmlPdf());
|
||||
|
||||
Button generateTestPdfFromHtmlButton = new Button("Test PDF aus vltInvoice.html erstellen");
|
||||
generateTestPdfFromHtmlButton.addClickListener(e -> generateTestPdfFromHtml());
|
||||
|
||||
Button showPdfInlineButton = new Button("PDF inline anzeigen");
|
||||
showPdfInlineButton.addClickListener(e -> showPdfInline());
|
||||
|
||||
// Create button layout
|
||||
HorizontalLayout buttonLayout = new HorizontalLayout();
|
||||
buttonLayout.add(generatePdfButton, generateHtmlPdfButton, generateTestPdfFromHtmlButton, showPdfInlineButton);
|
||||
buttonLayout.setSpacing(true);
|
||||
|
||||
// Initialize PDF viewer
|
||||
pdfViewer = new IFrame();
|
||||
pdfViewer.setWidth("100%");
|
||||
pdfViewer.setHeight("800px");
|
||||
pdfViewer.getStyle().set("border", "1px solid #ccc");
|
||||
pdfViewer.setVisible(false);
|
||||
|
||||
add(buttonLayout);
|
||||
add(pdfViewer);
|
||||
}
|
||||
|
||||
private void generateTestPdf() {
|
||||
@@ -58,5 +83,67 @@ public class PdfTestView extends VerticalLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateHtmlPdf() {
|
||||
try {
|
||||
byte[] pdfBytes = systemInvoiceService.generateInvoicePdfFromHtml();
|
||||
|
||||
}
|
||||
StreamResource resource = new StreamResource("vlt-invoice.pdf",
|
||||
() -> new ByteArrayInputStream(pdfBytes));
|
||||
resource.setContentType("application/pdf");
|
||||
|
||||
getUI().ifPresent(ui -> {
|
||||
var registration = ui.getSession().getResourceRegistry().registerResource(resource);
|
||||
ui.getPage().open(registration.getResourceUri().toString(), "_blank");
|
||||
});
|
||||
|
||||
Notification.show("PDF aus HTML erfolgreich generiert!", 3000, Notification.Position.BOTTOM_CENTER);
|
||||
} catch (Exception ex) {
|
||||
Notification.show("Fehler beim Generieren des PDFs aus HTML: " + ex.getMessage(),
|
||||
5000, Notification.Position.BOTTOM_CENTER);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateTestPdfFromHtml() {
|
||||
try {
|
||||
SystemInvoiceData sampleData = systemInvoiceService.createSampleInvoiceData();
|
||||
byte[] pdfBytes = systemInvoiceService.generateInvoicePdfFromHtml();
|
||||
|
||||
StreamResource resource = new StreamResource("test-invoice-from-html.pdf",
|
||||
() -> new ByteArrayInputStream(pdfBytes));
|
||||
resource.setContentType("application/pdf");
|
||||
|
||||
getUI().ifPresent(ui -> {
|
||||
var registration = ui.getSession().getResourceRegistry().registerResource(resource);
|
||||
ui.getPage().open(registration.getResourceUri().toString(), "_blank");
|
||||
});
|
||||
|
||||
Notification.show("Test PDF aus HTML erfolgreich generiert!", 3000, Notification.Position.BOTTOM_CENTER);
|
||||
} catch (Exception ex) {
|
||||
Notification.show("Fehler beim Generieren des Test PDFs aus HTML: " + ex.getMessage(),
|
||||
5000, Notification.Position.BOTTOM_CENTER);
|
||||
}
|
||||
}
|
||||
|
||||
private void showPdfInline() {
|
||||
try {
|
||||
SystemInvoiceData sampleData = systemInvoiceService.createSampleInvoiceData();
|
||||
byte[] pdfBytes = systemInvoiceService.generateInvoicePdf(sampleData);
|
||||
|
||||
StreamResource resource = new StreamResource("inline-invoice.pdf",
|
||||
() -> new ByteArrayInputStream(pdfBytes));
|
||||
resource.setContentType("application/pdf");
|
||||
|
||||
getUI().ifPresent(ui -> {
|
||||
var registration = ui.getSession().getResourceRegistry().registerResource(resource);
|
||||
pdfViewer.setSrc(registration.getResourceUri().toString());
|
||||
pdfViewer.setVisible(true);
|
||||
});
|
||||
|
||||
Notification.show("PDF wird inline angezeigt!", 3000, Notification.Position.BOTTOM_CENTER);
|
||||
} catch (Exception ex) {
|
||||
Notification.show("Fehler beim Anzeigen des PDFs: " + ex.getMessage(),
|
||||
5000, Notification.Position.BOTTOM_CENTER);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.itextpdf.html2pdf.HtmlConverter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -72,7 +74,7 @@ public class SystemInvoiceService {
|
||||
contentStream.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD), TITLE_FONT_SIZE);
|
||||
contentStream.setNonStrokingColor(27/255f, 18/255f, 185/255f); // Blue color (RGB values normalized to 0-1)
|
||||
contentStream.newLineAtOffset(MARGIN, yPosition);
|
||||
contentStream.showText(data.getCompanyName());
|
||||
contentStream.showText(data.getCompanyName() != null ? data.getCompanyName() : "");
|
||||
contentStream.endText();
|
||||
|
||||
yPosition -= 30;
|
||||
@@ -82,7 +84,7 @@ public class SystemInvoiceService {
|
||||
contentStream.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD), FONT_SIZE);
|
||||
contentStream.setNonStrokingColor(27/255f, 18/255f, 185/255f);
|
||||
contentStream.newLineAtOffset(MARGIN, yPosition);
|
||||
contentStream.showText(data.getCompanySubtitle());
|
||||
contentStream.showText(data.getCompanySubtitle() != null ? data.getCompanySubtitle() : "");
|
||||
contentStream.endText();
|
||||
|
||||
yPosition -= 20;
|
||||
@@ -108,7 +110,7 @@ public class SystemInvoiceService {
|
||||
contentStream.beginText();
|
||||
contentStream.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA), 8);
|
||||
contentStream.newLineAtOffset(leftColumn, yPosition);
|
||||
contentStream.showText(data.getSenderLine());
|
||||
contentStream.showText(data.getSenderLine() != null ? data.getSenderLine() : "");
|
||||
contentStream.endText();
|
||||
|
||||
yPosition -= 20;
|
||||
@@ -143,7 +145,7 @@ public class SystemInvoiceService {
|
||||
|
||||
contentStream.beginText();
|
||||
contentStream.newLineAtOffset(dateColumn, recipientStartY - LINE_HEIGHT);
|
||||
contentStream.showText(data.getInvoiceDate());
|
||||
contentStream.showText(data.getInvoiceDate() != null ? data.getInvoiceDate() : "");
|
||||
contentStream.endText();
|
||||
|
||||
// Company address (right side)
|
||||
@@ -158,7 +160,7 @@ public class SystemInvoiceService {
|
||||
contentStream.beginText();
|
||||
contentStream.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD), SUBTITLE_FONT_SIZE);
|
||||
contentStream.newLineAtOffset(MARGIN, yPosition);
|
||||
contentStream.showText("Rechnung " + data.getInvoiceNumber());
|
||||
contentStream.showText("Rechnung " + (data.getInvoiceNumber() != null ? data.getInvoiceNumber() : ""));
|
||||
contentStream.endText();
|
||||
|
||||
yPosition -= 30;
|
||||
@@ -307,7 +309,7 @@ public class SystemInvoiceService {
|
||||
// VAT
|
||||
contentStream.beginText();
|
||||
contentStream.newLineAtOffset(rightColumn, yPosition);
|
||||
contentStream.showText("+ " + data.getVatRate() + "% MwSt.:");
|
||||
contentStream.showText("+ " + (data.getVatRate() != null ? data.getVatRate() : "") + "% MwSt.:");
|
||||
contentStream.endText();
|
||||
|
||||
contentStream.beginText();
|
||||
@@ -431,4 +433,67 @@ public class SystemInvoiceService {
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] generateInvoicePdfFromHtml() throws Exception {
|
||||
// Read the HTML template
|
||||
String htmlContent = readHtmlTemplate();
|
||||
|
||||
// For simplicity, we'll use the existing sample data to fill the PDF
|
||||
SystemInvoiceData sampleData = createSampleInvoiceData();
|
||||
|
||||
// Replace placeholders in HTML with actual data
|
||||
String filledHtml = fillHtmlWithInvoiceData(htmlContent, sampleData);
|
||||
|
||||
// Create PDF from HTML using iText
|
||||
return generatePdfFromHtmlString(filledHtml);
|
||||
}
|
||||
|
||||
private String readHtmlTemplate() throws Exception {
|
||||
// Read the HTML template file
|
||||
java.nio.file.Path path = java.nio.file.Paths.get("src/main/resources/templates/vltInvoice.html");
|
||||
return java.nio.file.Files.readString(path);
|
||||
}
|
||||
|
||||
private String fillHtmlWithInvoiceData(String html, SystemInvoiceData data) {
|
||||
// Replace placeholders in HTML with actual invoice data
|
||||
String filledHtml = html;
|
||||
|
||||
filledHtml = filledHtml.replace("HHA-2021-07", data.getInvoiceNumber() != null ? data.getInvoiceNumber() : "");
|
||||
filledHtml = filledHtml.replace("19.07.2021", data.getInvoiceDate() != null ? data.getInvoiceDate() : "");
|
||||
filledHtml = filledHtml.replace("Gemäß unserem Nutzungsvertrag zu der Bestellnummer 45519389 berechnen wir Ihnen für den Monat Juli 2021 wie folgt:",
|
||||
data.getInvoiceText() != null ? data.getInvoiceText() : "");
|
||||
|
||||
// Replace recipient address
|
||||
filledHtml = filledHtml.replace("Hamburger Hochbahn AG<br>\n Kreditorenbuchhaltung<br>\n Steinstraße 20<br>\n 20095 Hamburg",
|
||||
data.getRecipientName() != null ? data.getRecipientName() : "" + "<br>\n " +
|
||||
(data.getRecipientDepartment() != null ? data.getRecipientDepartment() : "") + "<br>\n " +
|
||||
(data.getRecipientStreet() != null ? data.getRecipientStreet() : "") + "<br>\n " +
|
||||
(data.getRecipientCity() != null ? data.getRecipientCity() : ""));
|
||||
|
||||
// Replace invoice items
|
||||
if (data.getInvoiceItems() != null && !data.getInvoiceItems().isEmpty()) {
|
||||
SystemInvoiceItem item = data.getInvoiceItems().get(0);
|
||||
filledHtml = filledHtml.replace("1", item.getQuantity() != null ? item.getQuantity() : "");
|
||||
filledHtml = filledHtml.replace("Mtl. Lizenzgebühr »ILLT«", item.getDescription() != null ? item.getDescription() : "");
|
||||
filledHtml = filledHtml.replace("5.639,00 €", item.getUnitPrice() != null ? item.getUnitPrice() : "");
|
||||
filledHtml = filledHtml.replace("5.639,00 €", item.getTotalPrice() != null ? item.getTotalPrice() : "");
|
||||
}
|
||||
|
||||
// Replace amounts
|
||||
filledHtml = filledHtml.replace("5.639,00 €", data.getNetAmount() != null ? data.getNetAmount() : "");
|
||||
filledHtml = filledHtml.replace("1.071,41 €", data.getVatAmount() != null ? data.getVatAmount() : "");
|
||||
filledHtml = filledHtml.replace("6.710,41 €", data.getTotalAmount() != null ? data.getTotalAmount() : "");
|
||||
|
||||
return filledHtml;
|
||||
}
|
||||
|
||||
private byte[] generatePdfFromHtmlString(String htmlContent) throws Exception {
|
||||
// Create PDF using iText library
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
// Convert HTML to PDF using iText 8 HtmlConverter
|
||||
HtmlConverter.convertToPdf(htmlContent, baos);
|
||||
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
97
src/main/resources/templates/vltInvoice.html
Normal file
97
src/main/resources/templates/vltInvoice.html
Normal file
@@ -0,0 +1,97 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Rechnung VOTIAN-LT</title>
|
||||
<style>
|
||||
@page { size: A4; margin: 0; }
|
||||
html, body { margin: 0; padding: 0; width: 21cm; height: 29.7cm; }
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
padding: 2cm;
|
||||
border: 2px solid #1b12b9;
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 12pt;
|
||||
position: relative;
|
||||
}
|
||||
main { flex: 1 0 auto; }
|
||||
h1, h2 { color: #1b12b9; text-align: center; margin: 0; }
|
||||
table { width: 100%; border-collapse: collapse; margin-top: 1em; }
|
||||
th, td { padding: 0.3em; text-align: right; border-top: 1px solid #ddd; vertical-align: top; }
|
||||
th:first-child, td:first-child { text-align: left; }
|
||||
.total-row { font-weight: bold; background: #e6e6e6; }
|
||||
|
||||
/* Footer exakt 5cm über dem unteren Rand */
|
||||
.footer-section {
|
||||
position: absolute;
|
||||
bottom: 0cm; /* Abstand von unten */
|
||||
left: 2cm; /* gleiche Einrückung wie body-padding */
|
||||
right: 2cm;
|
||||
}
|
||||
|
||||
.footer { font-size: 10pt; text-align: center; margin-top: 1em; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<main>
|
||||
<h1>Assecutor</h1>
|
||||
<h2>Data Service GmbH1111</h2>
|
||||
|
||||
<p><strong>Empfänger:</strong><br>
|
||||
Hamburger Hochbahasdfasdasn AG<br>
|
||||
Kreditorenbuchhaltung<br>
|
||||
Steinstraße 20<br>
|
||||
20095 Hamburg
|
||||
</p>
|
||||
|
||||
<p><strong>Absender:</strong><br>
|
||||
Assecutor Data Service GmbH<br>
|
||||
Gerhart-Hauptmann-Weg 14, 21502 Geesthacht<br>
|
||||
Tel.: 040-181237710 · www.assecutor.de
|
||||
</p>
|
||||
|
||||
<p><strong>Datum:</strong> 19.07.2021</p>
|
||||
|
||||
<h2>Rechnung HHA-2021-07</h2>
|
||||
<p>Gemäß unserem Nutzungsvertrag zu der Bestellnummer <strong>45519389</strong>
|
||||
berechnen wir Ihnen für den Monat Juli 2021 wie folgt:</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Menge</th><th>Bezeichnung</th><th>Einzelpreis</th><th>Gesamt</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td style="text-align:left">
|
||||
Mtl. Lizenzgebühr »ILLT«
|
||||
</td>
|
||||
<td>5.639,00 €</td>
|
||||
<td>5.639,00 €</td>
|
||||
</tr>
|
||||
<tr class="total-row">
|
||||
<td></td><td style="text-align:left">Nettobetrag</td><td></td><td>5.639,00 €</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td style="text-align:left">+ 19% MwSt.</td><td></td><td>1.071,41 €</td>
|
||||
</tr>
|
||||
<tr class="total-row">
|
||||
<td></td><td style="text-align:left">Endbetrag</td><td></td><td>6.710,41 €</td>
|
||||
</tr>
|
||||
</table>
|
||||
</main>
|
||||
|
||||
<div class="footer-section">
|
||||
<p><strong>Zahlungsbedingungen:</strong> Gesamtbetrag bis spätestens zum 10. Werktag nach Rechnungserhalt auf unser Konto.</p>
|
||||
<br>
|
||||
<p class="footer">
|
||||
Geschäftsführer: Carsten Annacker, Gunnar Timm · Steuernummer: 22 294 53099 · USt-IdNr.: DE261094748<br>
|
||||
Sitz: Geesthacht · Handelsregister: Lübeck HRB 8595<br>
|
||||
Bankverbindung: Hamburger Sparkasse · IBAN DE67200505501217139888 · BIC HASPDEHHXXX
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user