diff --git a/modules/pom.xml b/modules/pom.xml
index 9214f520..c22d500f 100644
--- a/modules/pom.xml
+++ b/modules/pom.xml
@@ -34,6 +34,7 @@
batch
web
basic
+ reporting
diff --git a/modules/reporting/pom.xml b/modules/reporting/pom.xml
new file mode 100644
index 00000000..026a0957
--- /dev/null
+++ b/modules/reporting/pom.xml
@@ -0,0 +1,44 @@
+
+
+ 4.0.0
+
+ com.devonfw.java.dev
+ devon4j-modules
+ dev-SNAPSHOT
+
+ com.devonfw.java.modules
+ devon4j-reporting
+ ${devon4j.version}
+ jar
+ ${project.artifactId}
+ Module for reporting.
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ com.devonfw.java.modules
+ devon4j-test
+ test
+
+
+
+ net.sf.jasperreports
+ jasperreports
+ 6.11.0
+
+
+ org.apache.poi
+ poi
+ 4.1.1
+
+
+ net.sf.m-m-m
+ mmm-util-exception
+
+
+
+
diff --git a/modules/reporting/src/main/java/com/devonfw/module/reporting/common/ReportingModuleApp.java b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/ReportingModuleApp.java
new file mode 100644
index 00000000..cf0526f3
--- /dev/null
+++ b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/ReportingModuleApp.java
@@ -0,0 +1,22 @@
+package com.devonfw.module.reporting.common;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * This is the entry point for unit tests.
+ *
+ */
+@SpringBootApplication
+public class ReportingModuleApp {
+ /**
+ * Entry point for spring-boot based app
+ *
+ * @param args - arguments
+ */
+ public static void main(String[] args) {
+
+ SpringApplication.run(ReportingModuleApp.class, args);
+
+ }
+}
diff --git a/modules/reporting/src/main/java/com/devonfw/module/reporting/common/api/Report.java b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/api/Report.java
new file mode 100644
index 00000000..d6b57ff6
--- /dev/null
+++ b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/api/Report.java
@@ -0,0 +1,102 @@
+package com.devonfw.module.reporting.common.api;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class to encapsulate a report
+ *
+ * @param type of the data that is provided to be included in the report
+ */
+public class Report {
+ private String name;
+
+ private String dataSourceName;
+
+ private List data;
+
+ private String templatePath;
+
+ private HashMap params;
+
+ /**
+ * @return name
+ */
+ public String getName() {
+
+ return this.name;
+ }
+
+ /**
+ * @param name new value of {@link #getName}.
+ */
+ public void setName(String name) {
+
+ this.name = name;
+ }
+
+ /**
+ * @return dataSourceName
+ */
+ public String getDataSourceName() {
+
+ return this.dataSourceName;
+ }
+
+ /**
+ * @param dataSourceName new value of {@link #getDataSourceName}.
+ */
+ public void setDataSourceName(String dataSourceName) {
+
+ this.dataSourceName = dataSourceName;
+ }
+
+ /**
+ * @return data
+ */
+ public List getData() {
+
+ return this.data;
+ }
+
+ /**
+ * @param data new value of {@link #getData}.
+ */
+ public void setData(List data) {
+
+ this.data = data;
+ }
+
+ /**
+ * @return templatePath
+ */
+ public String getTemplatePath() {
+
+ return this.templatePath;
+ }
+
+ /**
+ * @param templatePath new value of {@link #getTemplatePath}.
+ */
+ public void setTemplatePath(String templatePath) {
+
+ this.templatePath = templatePath;
+ }
+
+ /**
+ * @return params
+ */
+ public Map getParams() {
+
+ return this.params;
+ }
+
+ /**
+ * @param params new value of {@link #getParams}.
+ */
+ public void setParams(HashMap params) {
+
+ this.params = params;
+ }
+}
diff --git a/modules/reporting/src/main/java/com/devonfw/module/reporting/common/api/Reporting.java b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/api/Reporting.java
new file mode 100644
index 00000000..7a76a20b
--- /dev/null
+++ b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/api/Reporting.java
@@ -0,0 +1,74 @@
+package com.devonfw.module.reporting.common.api;
+
+import java.io.File;
+import java.io.OutputStream;
+import java.util.List;
+
+/**
+ * This is the interface for a simple facade to generate a report based on Jasper Reports library.
+ *
+ * @param type of the data that is provided to be included in the report.
+ */
+public interface Reporting {
+
+ /**
+ * Generates a report file with the given data, the template located in the templatePath and the type of file.
+ * specified.
+ *
+ * @param report the {@link Report} that encapsulates the data to be included in the report, the location of the
+ * report template and the values of the parameters defined in the report template (in case template uses
+ * parameters).
+ * @param file the file where the report must be created.
+ * @param format - report format
+ */
+ public void generateReport(Report report, File file, String format);
+
+ /**
+ * Generates a report stream with the given data, the template located in the templatePath and the type of file.
+ *
+ * @param report the {@link Report} that encapsulates the data to be included in the report, the location of the
+ * report template and the values of the parameters defined in the report template (in case template uses
+ * parameters).
+ * @param stream the stream where the report will be written.
+ * @param format - report format
+ */
+ public void generateReport(Report report, OutputStream stream, String format);
+
+ /**
+ * Generates a file with a main report that stores other sub-reports.
+ *
+ * @param masterReport the main {@link Report}.
+ * @param reports a list of {@link Report} reports to be included within the main report.
+ * @param file the file where the report must be created.
+ * @param format - report format
+ */
+ public void generateSubreport(Report masterReport, List reports, File file, String format);
+
+ /**
+ * Generates a stream with a main report that stores other sub-reports.
+ *
+ * @param masterReport the main {@link Report}.
+ * @param reports a list of {@link Report} reports to be included within the main report.
+ * @param stream the stream to manage the resultant report.
+ * @param format - report format
+ */
+ public void generateSubreport(Report masterReport, List reports, OutputStream stream, String format);
+
+ /**
+ * Generates a report file that contains a concatenation of reports.
+ *
+ * @param reports the list of reports to be included in the report file.
+ * @param file the file where the report must be created.
+ * @param format - report format
+ */
+ public void concatenateReports(List reports, File file, String format);
+
+ /**
+ * Generates a stream that contains a concatenation of reports.
+ *
+ * @param reports the list of reports to be included in the report stream.
+ * @param stream the stream to manage the resultant report.
+ * @param format - report format
+ */
+ public void concatenateReports(List reports, OutputStream stream, String format);
+}
diff --git a/modules/reporting/src/main/java/com/devonfw/module/reporting/common/api/exception/ReportingException.java b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/api/exception/ReportingException.java
new file mode 100644
index 00000000..babd9e95
--- /dev/null
+++ b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/api/exception/ReportingException.java
@@ -0,0 +1,46 @@
+package com.devonfw.module.reporting.common.api.exception;
+
+import net.sf.mmm.util.exception.api.NlsRuntimeException;
+import net.sf.mmm.util.nls.api.NlsMessage;
+
+/**
+ * This is the checked exception for Reporting module.
+ *
+ */
+public class ReportingException extends NlsRuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The constructor.
+ *
+ * @param message the error {@link #getNlsMessage() message}.
+ */
+ public ReportingException(NlsMessage message) {
+
+ super(message);
+ }
+
+ /**
+ * Constructs an {@code ReportingException} with the root cause.
+ *
+ * @param cause the error {@link #getCause() cause}.
+ * @param message the error {@link #getNlsMessage() message}.
+ */
+ public ReportingException(Throwable cause, NlsMessage message) {
+
+ super(cause, message);
+ }
+
+ /**
+ * The constructor.
+ *
+ * @param cause the error {@link #getCause() cause}.
+ * @param message the error message.
+ */
+ public ReportingException(Throwable cause, String message) {
+
+ super(cause, message);
+ }
+
+}
diff --git a/modules/reporting/src/main/java/com/devonfw/module/reporting/common/config/ReportExporterConfiguration.java b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/config/ReportExporterConfiguration.java
new file mode 100644
index 00000000..5438c5ff
--- /dev/null
+++ b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/config/ReportExporterConfiguration.java
@@ -0,0 +1,217 @@
+package com.devonfw.module.reporting.common.config;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import net.sf.jasperreports.engine.JRAbstractExporter;
+import net.sf.jasperreports.engine.export.HtmlExporter;
+import net.sf.jasperreports.engine.export.JRCsvExporter;
+import net.sf.jasperreports.engine.export.JRPdfExporter;
+import net.sf.jasperreports.engine.export.JRRtfExporter;
+import net.sf.jasperreports.engine.export.JRTextExporter;
+import net.sf.jasperreports.engine.export.JRXlsExporter;
+import net.sf.jasperreports.engine.export.oasis.JROdsExporter;
+import net.sf.jasperreports.engine.export.oasis.JROdtExporter;
+import net.sf.jasperreports.engine.export.ooxml.JRDocxExporter;
+import net.sf.jasperreports.engine.export.ooxml.JRPptxExporter;
+import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Configuration class that returns the {@link JRAbstractExporter exporter} according to the {@link ReportingConstants}
+ *
+ */
+@Configuration
+public class ReportExporterConfiguration {
+
+ private final Map exporterMap;
+
+ /**
+ * The constructor.
+ */
+ public ReportExporterConfiguration() {
+
+ super();
+ this.exporterMap = new HashMap<>();
+ }
+
+ /**
+ * puts the {@link JRAbstractExporter} Instance in to the {@link Map} according to {@link ReportingConstants}
+ *
+ * @param jrAbstractExporters
+ */
+ @Inject
+ public void setReportExporters(List jrAbstractExporters) {
+
+ for (JRAbstractExporter exporter : jrAbstractExporters) {
+ this.exporterMap.put(exporter.getExporterKey(), exporter);
+ }
+
+ }
+
+ @Bean
+ public JRAbstractExporter getExcelExporter() {
+
+ return new JRXlsExporter() {
+ @Override
+ public String getExporterKey() {
+
+ return ReportingConstants.XLS;
+ }
+ };
+ }
+
+ /**
+ * Returns the {@link JRAbstractExporter} for Xls version
+ *
+ * @return
+ */
+ @Bean
+ public JRAbstractExporter getPdfExporter() {
+
+ return new JRPdfExporter() {
+ @Override
+ public String getExporterKey() {
+
+ return ReportingConstants.PDF;
+ }
+ };
+ }
+
+ @Bean
+ public JRAbstractExporter getCsvExporter() {
+
+ return new JRCsvExporter() {
+ @Override
+ public String getExporterKey() {
+
+ return ReportingConstants.CSV;
+ }
+ };
+ }
+
+ @Bean
+ public JRAbstractExporter getRtfExporter() {
+
+ return new JRRtfExporter() {
+ @Override
+ public String getExporterKey() {
+
+ return ReportingConstants.RTF;
+ }
+ };
+ }
+
+ @Bean
+ public JRAbstractExporter getWordExporter() {
+
+ return new JRRtfExporter() {
+ @Override
+ public String getExporterKey() {
+
+ return ReportingConstants.WORD;
+ }
+ };
+ }
+
+ @Bean
+ public JRAbstractExporter getTextExporter() {
+
+ return new JRTextExporter() {
+ @Override
+ public String getExporterKey() {
+
+ return ReportingConstants.TEXT;
+ }
+ };
+ }
+
+ @Bean
+ public JRAbstractExporter getDocxExporter() {
+
+ return new JRDocxExporter() {
+ @Override
+ public String getExporterKey() {
+
+ return ReportingConstants.DOCX;
+ }
+ };
+ }
+
+ @Bean
+ public JRAbstractExporter getXlsxExporter() {
+
+ return new JRXlsxExporter() {
+ @Override
+ public String getExporterKey() {
+
+ return ReportingConstants.XLSX;
+ }
+ };
+ }
+
+ @Bean
+ public JRAbstractExporter getHtmlExporter() {
+
+ return new HtmlExporter() {
+ @Override
+ public String getExporterKey() {
+
+ return ReportingConstants.HTML;
+ }
+ };
+ }
+
+ @Bean
+ public JRAbstractExporter getOdtExporter() {
+
+ return new JROdtExporter() {
+ @Override
+ public String getExporterKey() {
+
+ return ReportingConstants.ODT;
+ }
+ };
+ }
+
+ @Bean
+ public JRAbstractExporter getOdsExporter() {
+
+ return new JROdsExporter() {
+ @Override
+ public String getExporterKey() {
+
+ return ReportingConstants.ODS;
+ }
+ };
+ }
+
+ @Bean
+ public JRAbstractExporter getPptxExporter() {
+
+ return new JRPptxExporter() {
+ @Override
+ public String getExporterKey() {
+
+ return ReportingConstants.PPTX;
+ }
+ };
+ }
+
+ /**
+ * Returns the {@link JRAbstractExporter} instance
+ *
+ * @param format key according the {@link ReportingConstants}
+ * @return
+ */
+ public JRAbstractExporter getReportExporter(String format) {
+
+ return this.exporterMap.get(format);
+ }
+
+}
diff --git a/modules/reporting/src/main/java/com/devonfw/module/reporting/common/config/ReportingConfigProperties.java b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/config/ReportingConfigProperties.java
new file mode 100644
index 00000000..6b4378ab
--- /dev/null
+++ b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/config/ReportingConfigProperties.java
@@ -0,0 +1,34 @@
+package com.devonfw.module.reporting.common.config;
+
+import java.util.HashMap;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Configuration for Reporting
+ */
+@Configuration
+@ConfigurationProperties(prefix = "jasper.reporting")
+public class ReportingConfigProperties {
+
+ private HashMap txtConfig;
+
+ /**
+ * @return txtConfig
+ */
+
+ public HashMap getTxtConfig() {
+
+ return this.txtConfig;
+ }
+
+ /**
+ * @param txtConfig collection of properties
+ */
+ public void setTxtConfig(HashMap txtConfig) {
+
+ this.txtConfig = txtConfig;
+ }
+
+}
diff --git a/modules/reporting/src/main/java/com/devonfw/module/reporting/common/config/ReportingConstants.java b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/config/ReportingConstants.java
new file mode 100644
index 00000000..fa161a7a
--- /dev/null
+++ b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/config/ReportingConstants.java
@@ -0,0 +1,66 @@
+package com.devonfw.module.reporting.common.config;
+
+/**
+ * Constants of types of file outputs for the report.
+ */
+public class ReportingConstants {
+ /**
+ * Format type PDF
+ */
+ public static final String PDF = "pdf";
+
+ /**
+ * Format type EXCEL
+ */
+ public static final String XLS = "xls";
+
+ /**
+ * Format type TEXT
+ */
+ public static final String TEXT = "text";
+
+ /**
+ * Format type CSV
+ */
+ public static final String CSV = "csv";
+
+ /**
+ * Format type HTML
+ */
+ public static final String HTML = "html";
+
+ /**
+ * Format type WORD
+ */
+ public static final String WORD = "word";
+
+ /**
+ * Format type RTF
+ */
+ public static final String RTF = "rtf";
+
+ /**
+ * Format type TEXT
+ */
+ public static final String DOCX = "docx";
+
+ /**
+ * Format type EXCEL XLSX
+ */
+ public static final String XLSX = "xlsx";
+
+ /**
+ * Format type OPEN DOCUMENT TEXT
+ */
+ public static final String ODT = "odt";
+
+ /**
+ * Format type OPEN DOCUMENT SHEET
+ */
+ public static final String ODS = "ods";
+
+ /**
+ * Format type PPTX
+ */
+ public static final String PPTX = "pptx";
+}
diff --git a/modules/reporting/src/main/java/com/devonfw/module/reporting/common/config/ReportingUtil.java b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/config/ReportingUtil.java
new file mode 100644
index 00000000..75d905a9
--- /dev/null
+++ b/modules/reporting/src/main/java/com/devonfw/module/reporting/common/config/ReportingUtil.java
@@ -0,0 +1,140 @@
+package com.devonfw.module.reporting.common.config;
+
+import java.io.OutputStream;
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import net.sf.jasperreports.engine.JRAbstractExporter;
+import net.sf.jasperreports.engine.JRDataSource;
+import net.sf.jasperreports.engine.JREmptyDataSource;
+import net.sf.jasperreports.engine.JasperPrint;
+import net.sf.jasperreports.engine.data.JRMapCollectionDataSource;
+import net.sf.jasperreports.export.ExporterInput;
+import net.sf.jasperreports.export.ExporterOutput;
+import net.sf.jasperreports.export.SimpleExporterInput;
+import net.sf.jasperreports.export.SimpleHtmlExporterOutput;
+import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
+import net.sf.jasperreports.export.SimpleTextReportConfiguration;
+import net.sf.jasperreports.export.SimpleWriterExporterOutput;
+import net.sf.jasperreports.export.SimpleXlsReportConfiguration;
+import net.sf.jasperreports.export.SimpleXlsxReportConfiguration;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.devonfw.module.reporting.common.api.exception.ReportingException;
+
+/**
+ * This is the implementation of several basic functionalities associated to Jasper Reports Library.
+ */
+@Named
+public class ReportingUtil {
+
+ private static final Log log = LogFactory.getLog(ReportingUtil.class);
+
+ @Inject
+ private ReportingConfigProperties reportingConfigProperties;
+
+ /**
+ * Returns the data provided as JRDataSource type in order to fill the report.
+ *
+ * @param data the data to be included in the report.
+ * @return {@link JRDataSource}
+ */
+ public JRDataSource getDataSource(Collection extends Object> data) {
+
+ if (data.size() == 0) {
+ return new JREmptyDataSource();
+ } else {
+ return new JRMapCollectionDataSource((Collection