package org.mapfish.print.processor.jasper; import com.google.common.annotations.VisibleForTesting; import com.google.common.io.Files; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JasperCompileManager; import net.sf.jasperreports.engine.Renderable; import net.sf.jasperreports.engine.design.JRDesignBand; import net.sf.jasperreports.engine.design.JRDesignElement; import net.sf.jasperreports.engine.design.JRDesignExpression; import net.sf.jasperreports.engine.design.JRDesignImage; import net.sf.jasperreports.engine.design.JasperDesign; import net.sf.jasperreports.engine.type.HorizontalImageAlignEnum; import net.sf.jasperreports.engine.type.ScaleImageEnum; import net.sf.jasperreports.engine.type.WhenNoDataTypeEnum; import java.awt.Dimension; import java.io.File; import java.net.URI; import java.util.List; /** * Creates a Jasper containing overlaid images, which is supposed to * be embedded into an another report as sub-report. */ public class ImagesSubReport { private final JasperDesign reportDesign; /** * Constructor. * * @param graphics A list of graphic files. * @param size The size of the report in pixel. * @param dpi the dpi of the report */ public ImagesSubReport(final List<URI> graphics, final Dimension size, final double dpi) { this.reportDesign = createReport(graphics, size, dpi); } private JasperDesign createReport(final List<URI> graphics, final Dimension size, final double dpi) { final JasperDesign design = new JasperDesign(); design.setName("map"); // report size and margins design.setPageWidth(size.width); design.setPageHeight(size.height); design.setColumnWidth(size.width); design.setColumnSpacing(0); design.setLeftMargin(0); design.setRightMargin(0); design.setTopMargin(0); design.setBottomMargin(0); JRDesignBand band = new JRDesignBand(); band.setHeight(size.height); // add layer graphics to report addGraphics(graphics, band, size, design); // note that the images are added to the "NoData" band, this ensures // that they are displayed even if no data connection is passed to the // sub-report design.setNoData(band); design.setWhenNoDataType(WhenNoDataTypeEnum.NO_DATA_SECTION); design.setProperty(Renderable.PROPERTY_IMAGE_DPI, String.valueOf(Math.round(dpi))); return design; } private void addGraphics(final List<URI> graphics, final JRDesignBand band, final Dimension size, final JasperDesign design) { for (URI graphicFile : graphics) { String imageExpression; final String fileName = new File(graphicFile).getAbsolutePath().replace('\\', '/'); if (Files.getFileExtension(fileName).equals("svg")) { imageExpression = "net.sf.jasperreports.renderers.BatikRenderer.getInstance(new java.io.File(\"" + fileName + "\"))"; } else { imageExpression = "\"" + fileName + "\""; } band.addElement(getImage(imageExpression, size, design)); } } private JRDesignElement getImage(final String imageExpression, final Dimension mapSize, final JasperDesign design) { final JRDesignImage image = new JRDesignImage(design); image.setHorizontalImageAlign(HorizontalImageAlignEnum.CENTER); image.setX(0); image.setY(0); image.setWidth(mapSize.width); image.setHeight(mapSize.height); image.setScaleImage(ScaleImageEnum.RETAIN_SHAPE); final JRDesignExpression expression = new JRDesignExpression(); expression.setText(imageExpression); image.setExpression(expression); return image; } /** * Compiles the report into a <code>*.jasper</code> file. * * @param compiledReportFile The destination file. * @throws JRException */ public final void compile(final File compiledReportFile) throws JRException { JasperCompileManager.compileReportToFile(this.reportDesign, compiledReportFile.getAbsolutePath()); } @VisibleForTesting protected final JasperDesign getReportDesign() { return this.reportDesign; } }