public byte[] generateReport(String templatePath, ReportType type, Long from, Long to) throws ServletException, IOException {

        if (from == null) {
            throw new IllegalArgumentException("report start date cannot be null");
        }

        if (to == null) {
            throw new IllegalArgumentException("report end date cannot be null");
        }

        if (to < from) {
            throw new IllegalArgumentException("Report end date must be after start date");
        }

        ResultSet results = null;

        try {

            if (preparedStatement == null) {
                preparedStatement = connection.prepareStatement(REPORT_QUERY);
            }

            connection.setAutoCommit(false);

            preparedStatement.setLong(1, from);
            preparedStatement.setLong(2, to);

            results = preparedStatement.executeQuery();

            JRResultSetDataSource resultSetDataSource = new JRResultSetDataSource(results);
            ByteArrayOutputStream os = new ByteArrayOutputStream();

            try {

                Map<String, Object> parameters = new HashMap<String, Object>();
                parameters.put("ReportTitle", "Capacity Per Employee");

                JasperPrint jasperPrint = JasperFillManager.fillReport(templatePath, parameters, resultSetDataSource);
                if (type == ReportType.PDF) {
                    JasperExportManager.exportReportToPdfStream(jasperPrint, os);
                } else {

                    JRCsvExporter csvExporter = new JRCsvExporter();
                    csvExporter.setParameter(JRCsvExporterParameter.FIELD_DELIMITER, ",");
                    csvExporter.setParameter(JRCsvExporterParameter.RECORD_DELIMITER, "\n");
                    csvExporter.setParameter(JRCsvExporterParameter.JASPER_PRINT, jasperPrint);
                    csvExporter.setParameter(JRCsvExporterParameter.IGNORE_PAGE_MARGINS, true);
                    csvExporter.setParameter(JRCsvExporterParameter.OUTPUT_STREAM, os);
                    csvExporter.exportReport();

                }

                return os.toByteArray();

            } catch (JRException e) {
                e.printStackTrace();
                throw new RuntimeException("Error occurred in report generation", e);
            }

        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (results != null) {
                    results.close();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }
    }