From 1741ccc67a9d33103231bf0bcb9e7dc13f2b0a64 Mon Sep 17 00:00:00 2001 From: Sven Carstensen Date: Fri, 17 Jul 2026 10:39:09 +0200 Subject: [PATCH] refactor: ZIP-Download in AdminCreateInvoicesView auf StreamResource umgestellt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Statt Base64-Data-URL per executeJs wird das ZIP nun wie in InvoicesView als StreamResource registriert und heruntergeladen — robuster bei großen Sammel-ZIPs. Co-Authored-By: Claude Fable 5 --- .../pages/view/AdminCreateInvoicesView.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/de/assecutor/votianlt/pages/view/AdminCreateInvoicesView.java b/backend/src/main/java/de/assecutor/votianlt/pages/view/AdminCreateInvoicesView.java index e28ef2a..9b84939 100644 --- a/backend/src/main/java/de/assecutor/votianlt/pages/view/AdminCreateInvoicesView.java +++ b/backend/src/main/java/de/assecutor/votianlt/pages/view/AdminCreateInvoicesView.java @@ -1,5 +1,6 @@ package de.assecutor.votianlt.pages.view; +import com.vaadin.flow.component.UI; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.button.ButtonVariant; import com.vaadin.flow.component.dialog.Dialog; @@ -19,6 +20,8 @@ import com.vaadin.flow.component.textfield.NumberField; import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.router.HasDynamicTitle; import com.vaadin.flow.router.Route; +import com.vaadin.flow.server.StreamRegistration; +import com.vaadin.flow.server.StreamResource; import com.vaadin.flow.theme.lumo.LumoUtility; import de.assecutor.votianlt.model.PriceTable; import de.assecutor.votianlt.model.User; @@ -40,6 +43,7 @@ import de.assecutor.votianlt.util.DateTimeFormatUtil; import jakarta.annotation.security.RolesAllowed; import lombok.extern.slf4j.Slf4j; +import java.io.ByteArrayInputStream; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; @@ -839,11 +843,12 @@ public class AdminCreateInvoicesView extends Main implements HasDynamicTitle { /** Offers the given ZIP bytes as browser download. */ private void triggerZipDownload(byte[] zip, String fileName) { - String base64Zip = Base64.getEncoder().encodeToString(zip); - getElement().executeJs("const link = document.createElement('a');" - + "link.href = 'data:application/zip;base64," + base64Zip + "';" + "link.download = '" - + fileName.replace("'", "") + "';" - + "document.body.appendChild(link); link.click(); document.body.removeChild(link);"); + StreamResource resource = new StreamResource(fileName, () -> new ByteArrayInputStream(zip)); + resource.setContentType("application/zip"); + resource.setCacheTime(0); + StreamRegistration registration = UI.getCurrent().getSession().getResourceRegistry() + .registerResource(resource); + UI.getCurrent().getPage().open(registration.getResourceUri().toString()); } /**