diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/ExcelExportController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/ExcelExportController.java index d8849fe..4ebd982 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/ExcelExportController.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/mahnlauf/ExcelExportController.java @@ -1,22 +1,30 @@ package com.alexanderlogistics.mahnlauf; +import java.io.IOException; +import java.io.OutputStream; import java.io.Serializable; import java.text.SimpleDateFormat; import java.time.YearMonth; import java.time.ZoneId; import java.util.Calendar; +import java.util.Collection; import java.util.Date; import java.util.logging.Logger; +import org.imixs.archive.core.SnapshotService; +import org.imixs.workflow.FileData; import org.imixs.workflow.ItemCollection; import org.imixs.workflow.engine.DocumentService; import org.imixs.workflow.exceptions.PluginException; +import org.imixs.workflow.exceptions.QueryException; import org.imixs.workflow.faces.data.DocumentController; import org.imixs.workflow.faces.data.WorkflowController; import org.imixs.workflow.office.forms.CustomFormItem; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ConversationScoped; +import jakarta.faces.context.ExternalContext; +import jakarta.faces.context.FacesContext; import jakarta.inject.Inject; import jakarta.inject.Named; @@ -36,6 +44,9 @@ public class ExcelExportController implements Serializable { private static final long serialVersionUID = 1L; private static Logger logger = Logger.getLogger(ExcelExportController.class.getName()); + public static final String ERROR_CONFIG = "CONFIG_ERROR"; + final String TYPE_TEXTBLOCK = "textblock"; + @Inject protected DocumentService documentService; @@ -45,6 +56,9 @@ public class ExcelExportController implements Serializable { @Inject DocumentController documentController; + @Inject + SnapshotService snapshotService; + private ItemCollection filter; private CustomFormItem dbtrItem; @@ -69,7 +83,7 @@ public class ExcelExportController implements Serializable { * * @throws PluginException */ - public void export() throws PluginException { + public String export() throws PluginException { logger.info("start export...."); @@ -115,7 +129,85 @@ public class ExcelExportController implements Serializable { query += " AND (dbtr.number:" + workflowController.getWorkitem().getItemValueString("dbtr.number") + ")"; } + // load the text block + String template = "ausgangsrechnungen-export_template.xlsx"; + FileData fileData = loadTextBlockFileData("Excel-Export Template", template); + + // do we found the document? + if (fileData == null) { + throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG, + "Missing Excel Export Template - template=" + template + " not found!"); + } + String targetName = "ausgangsrechnungen-export_" + dateformat.format(new Date()) + ".xlsx"; + fileData.setName(targetName); + + try { + // See: + // https://stackoverflow.com/questions/9391838/how-to-provide-a-file-download-from-a-jsf-backing-bean + download(fileData); + } catch (IOException e) { + throw new PluginException(InkassoExportAdapter.class.getSimpleName(), ERROR_CONFIG, + "Failed to generate Excel Export: " + e.getMessage()); + } + logger.info("Query=" + query); + return "/pages/admin/excel_export_rechnungsausgang.jsf?faces-redirect=true"; + } + + /** + * Helper method to initialize a download + * + * @throws IOException + */ + public void download(FileData fileData) throws IOException { + + FacesContext facesContext = FacesContext.getCurrentInstance(); + ExternalContext externalContext = facesContext.getExternalContext(); + + externalContext.responseReset(); + externalContext.setResponseContentType("application/vnd.ms-excel"); + externalContext.setResponseContentLength(fileData.getContent().length); + externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileData.getName() + "\""); + + OutputStream output = externalContext.getResponseOutputStream(); + + // Now you can write the InputStream of the file to the above OutputStream the + // usual way. + output.write(fileData.getContent()); + + facesContext.responseComplete(); // Important! Otherwise Faces will attempt to render the response which + // obviously will fail since it's already written with a file and closed. + } + + /** + * This method returns a text-block ItemCollection for a specified name. + * + * @param name in attribute txtname + * + * + */ + private FileData loadTextBlockFileData(String name, String fileName) { + ItemCollection textBlockItemCollection = null; + + // load text-block by name.... + String sQuery = "(type:\"" + TYPE_TEXTBLOCK + "\" AND txtname:\"" + name + "\")"; + Collection col; + try { + // find the textblock... + col = documentService.find(sQuery, 1, 0); + if (col.size() > 0) { + textBlockItemCollection = col.iterator().next(); + // fetch the fileData... + return snapshotService.getWorkItemFile(textBlockItemCollection.getUniqueID(), fileName); + + } else { + logger.warning("Missing text-block : '" + name + "'"); + } + } catch (QueryException e) { + logger.warning("getTextBlock - invalid query: " + e.getMessage()); + } + + return null; } /** diff --git a/office-alexander-logistics-app/src/main/webapp/pages/admin/excel_export_rechnungsausgang.xhtml b/office-alexander-logistics-app/src/main/webapp/pages/admin/excel_export_rechnungsausgang.xhtml index 903ac96..7814577 100644 --- a/office-alexander-logistics-app/src/main/webapp/pages/admin/excel_export_rechnungsausgang.xhtml +++ b/office-alexander-logistics-app/src/main/webapp/pages/admin/excel_export_rechnungsausgang.xhtml @@ -117,9 +117,10 @@ - - + x + diff --git a/templates/ausgangsrechnungen-export_template.xlsx b/templates/ausgangsrechnungen-export_template.xlsx new file mode 100644 index 0000000..1d2475b Binary files /dev/null and b/templates/ausgangsrechnungen-export_template.xlsx differ