/** * Copyright (c) 2013-2016, The SeedStack authors <http://seedstack.org> * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.seedstack.io.jasper.internal; import com.google.common.collect.Lists; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRExporter; import net.sf.jasperreports.engine.JRExporterParameter; import net.sf.jasperreports.engine.JasperCompileManager; import net.sf.jasperreports.engine.JasperFillManager; import net.sf.jasperreports.engine.JasperPrint; import net.sf.jasperreports.engine.JasperReport; import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; import net.sf.jasperreports.engine.design.JasperDesign; import net.sf.jasperreports.engine.export.HtmlExporter; import net.sf.jasperreports.engine.export.JRPdfExporter; import net.sf.jasperreports.engine.export.JRRtfExporter; import net.sf.jasperreports.engine.export.JRXhtmlExporter; import net.sf.jasperreports.engine.export.JRXlsAbstractExporterParameter; 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.seedstack.io.jasper.JasperTemplate; import org.seedstack.io.spi.AbstractTemplateRenderer; import org.seedstack.seed.SeedException; import javax.inject.Named; import java.io.OutputStream; import java.util.Collection; import java.util.Map; import java.util.Map.Entry; @Named("JasperRenderer") class JasperRenderer extends AbstractTemplateRenderer<JasperTemplate> { private static final String TEMPLATE = "template"; private JasperReport jasperReport; @Override public void render(OutputStream outputStream, Object object, String mimeType, Map<String, Object> parameters) { try { if (jasperReport == null) { // Convert template to JasperDesign JasperDesign jd = template.getJasperDesign(); // Compile report try { jasperReport = JasperCompileManager.compileReport(jd); } catch (NoClassDefFoundError error) { // Show an appropriate exception when jasper template language is set to Groovy if ("org/codehaus/groovy/control/CompilationFailedException".equals(error.getMessage())) { throw SeedException.wrap(error, JasperErrorCode.ERROR_DURING_JASPER_REPORT_COMPILATION) .put(TEMPLATE, template.getName()); } else { throw SeedException.wrap(error, JasperErrorCode.ERROR_DURING_JASPER_REPORT_COMPILATION) .put(TEMPLATE, template.getName()); } // Catch all possible fails when compiling a jasper report } catch (Exception e) { throw SeedException.wrap(e, JasperErrorCode.ERROR_DURING_JASPER_REPORT_COMPILATION) .put(TEMPLATE, template.getName()); } } // If model is not already a collection add it in a new collection Collection<?> col; if (object instanceof Collection) { col = (Collection<?>) object; } else { col = Lists.newArrayList(object); } // Create the JasperPrint object JasperPrint jp = JasperFillManager.fillReport(jasperReport, parameters, new JRBeanCollectionDataSource( col)); // Export report export(mimeType, jp, outputStream); // // Catch all possible fails when render a jasper report // } catch (Exception e) { throw SeedException.wrap(e, JasperErrorCode.ERROR_DURING_JASPER_REPORT_RENDERING); } } @Override public void render(OutputStream outputStream, Object model) { throw new IllegalArgumentException("Ambiguous MIME type, JasperRenderer does not support default MIME type"); } /** * Exports by MIME type. * * @param mimeType MIME type * @param jp Jasper print * @param os outputstream * @throws JRException */ protected void export(String mimeType, JasperPrint jp, OutputStream os) throws JRException { if ("application/pdf".equalsIgnoreCase(mimeType)) { exportReport(new JRPdfExporter(), jp, os); } else if ("text/xml".equalsIgnoreCase(mimeType)) { exportReport(new HtmlExporter(), jp, os); } else if ("application/rtf".equalsIgnoreCase(mimeType)) { exportReport(new JRRtfExporter(), jp, os); } else if ("application/xls".equalsIgnoreCase(mimeType)) { exportReport(new JRXlsExporter(), jp, os); } else if ("application/odt".equalsIgnoreCase(mimeType)) { exportReport(new JROdtExporter(), jp, os); } else if ("application/ods".equalsIgnoreCase(mimeType)) { exportReport(new JROdsExporter(), jp, os); } else if ("application/docx".equalsIgnoreCase(mimeType)) { exportReport(new JRDocxExporter(), jp, os); } else if ("application/xlsx".equalsIgnoreCase(mimeType)) { exportReport(new JRXlsxExporter(), jp, os); } else if ("application/pptx".equalsIgnoreCase(mimeType)) { exportReport(new JRPptxExporter(), jp, os); } else if ("text/xhmtl".equalsIgnoreCase(mimeType)) { exportReport(new JRXhtmlExporter(), jp, os); } else { throw new IllegalArgumentException("JasperRenderer does not support " + mimeType + " MIME type."); } } /** * Xls export. * * @param jp * @param os */ protected void exportXls(JasperPrint jp, OutputStream os) { // Create a JRXlsExporter instance JRXlsExporter exporter = new JRXlsExporter(); // Here we assign the parameters jp and baos to the exporter exporter.setParameter(JRExporterParameter.JASPER_PRINT, jp); exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os); // TODO add Excel specific parameters exporter.setParameter(JRXlsAbstractExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE); exporter.setParameter(JRXlsAbstractExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE); exporter.setParameter(JRXlsAbstractExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE); try { exporter.exportReport(); } catch (JRException e) { throw new RuntimeException(e); } } /** * @throws JRException */ protected void exportReport(JRExporter exporter, JasperPrint jp, OutputStream os) throws JRException { exporter.setParameter(JRExporterParameter.JASPER_PRINT, jp); exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os); if (template.getJrExporterParameters() != null) { for (Entry<JRExporterParameter, Object> entry : template.getJrExporterParameters().entrySet()) { exporter.setParameter(entry.getKey(), entry.getValue()); } } try { exporter.exportReport(); } catch (JRException e) { throw new RuntimeException(e); } } }