All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.jasperreports.engine.export.oasis.JROdtExporter Maven / Gradle / Ivy

There is a newer version: 6.21.3
Show newest version
/*
 * JasperReports - Free Java Reporting Library.
 * Copyright (C) 2001 - 2022 TIBCO Software Inc. All rights reserved.
 * http://www.jaspersoft.com
 *
 * Unless you have purchased a commercial license agreement from Jaspersoft,
 * the following license terms apply:
 *
 * This program is part of JasperReports.
 *
 * JasperReports is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * JasperReports is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with JasperReports. If not, see .
 */

/*
 * Special thanks to Google 'Summer of Code 2005' program for supporting this development
 *
 * Contributors:
 * Majid Ali Khan - [email protected]
 * Frank Schönheit - [email protected]
 */
package net.sf.jasperreports.engine.export.oasis;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.geom.Dimension2D;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import net.sf.jasperreports.engine.DefaultJasperReportsContext;
import net.sf.jasperreports.engine.JRAbstractExporter;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRGenericElementType;
import net.sf.jasperreports.engine.JRGenericPrintElement;
import net.sf.jasperreports.engine.JRPrintElement;
import net.sf.jasperreports.engine.JRPrintElementIndex;
import net.sf.jasperreports.engine.JRPrintEllipse;
import net.sf.jasperreports.engine.JRPrintFrame;
import net.sf.jasperreports.engine.JRPrintHyperlink;
import net.sf.jasperreports.engine.JRPrintImage;
import net.sf.jasperreports.engine.JRPrintLine;
import net.sf.jasperreports.engine.JRPrintPage;
import net.sf.jasperreports.engine.JRPrintRectangle;
import net.sf.jasperreports.engine.JRPrintText;
import net.sf.jasperreports.engine.JRPropertiesUtil;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.PrintPageFormat;
import net.sf.jasperreports.engine.export.CutsInfo;
import net.sf.jasperreports.engine.export.ElementGridCell;
import net.sf.jasperreports.engine.export.ExporterNature;
import net.sf.jasperreports.engine.export.GenericElementHandlerEnviroment;
import net.sf.jasperreports.engine.export.Grid;
import net.sf.jasperreports.engine.export.GridRow;
import net.sf.jasperreports.engine.export.JRExportProgressMonitor;
import net.sf.jasperreports.engine.export.JRExporterGridCell;
import net.sf.jasperreports.engine.export.JRGridLayout;
import net.sf.jasperreports.engine.export.JRHyperlinkProducer;
import net.sf.jasperreports.engine.export.JRXmlExporter;
import net.sf.jasperreports.engine.export.LengthUtil;
import net.sf.jasperreports.engine.export.zip.ExportZipEntry;
import net.sf.jasperreports.engine.export.zip.FileBufferedZipEntry;
import net.sf.jasperreports.engine.type.ModeEnum;
import net.sf.jasperreports.engine.util.ExifOrientationEnum;
import net.sf.jasperreports.engine.util.ImageUtil;
import net.sf.jasperreports.engine.util.ImageUtil.Insets;
import net.sf.jasperreports.engine.util.JRStringUtil;
import net.sf.jasperreports.engine.util.JRStyledText;
import net.sf.jasperreports.export.ExportInterruptedException;
import net.sf.jasperreports.export.ExporterInputItem;
import net.sf.jasperreports.export.OdtExporterConfiguration;
import net.sf.jasperreports.export.OdtReportConfiguration;
import net.sf.jasperreports.export.OutputStreamExporterOutput;
import net.sf.jasperreports.export.ReportExportConfiguration;
import net.sf.jasperreports.renderers.DataRenderable;
import net.sf.jasperreports.renderers.DimensionRenderable;
import net.sf.jasperreports.renderers.Renderable;
import net.sf.jasperreports.renderers.RenderersCache;
import net.sf.jasperreports.renderers.ResourceRenderer;


/**
 * Exports a JasperReports document to ODF format. It has character output type and exports the document to a
 * grid-based layout.
 * 

* Open Document Format (short for OASIS Open Document Format for Office * Applications) describes electronic documents such as memos, spreadsheets, books, * charts, presentations, and word processing documents. .odt is the * file extension used for the word processing documents in the Open Document Format, and such * files can be obtained in JasperReports using the * {@link net.sf.jasperreports.engine.export.oasis.JROdtExporter} class. *

* Currently, there are the following special configurations that can be applied to an ODT * exporter instance (see {@link net.sf.jasperreports.export.DocxReportConfiguration}) to customize * its behavior: *

    *
  • Allowing table rows to adjust their height if more text is typed into their cells using * the ODT editor. This is controlled using either the * {@link net.sf.jasperreports.export.OdtReportConfiguration#isFlexibleRowHeight() isFlexibleRowHeight()} * exporter configuration flag, or its corresponding exporter hint called * {@link net.sf.jasperreports.export.OdtReportConfiguration#PROPERTY_ODT_FLEXIBLE_ROW_HEIGHT net.sf.jasperreports.export.odt.flexible.row.height}.
  • *
  • Ignoring hyperlinks in generated documents if they are not intended for the ODT output format. This can be * customized using either the * {@link net.sf.jasperreports.export.OdtReportConfiguration#isIgnoreHyperlink() isIgnoreHyperlink()} * exporter configuration flag, or its corresponding exporter hint called * {@link net.sf.jasperreports.export.OdtReportConfiguration#PROPERTY_IGNORE_HYPERLINK net.sf.jasperreports.export.odt.ignore.hyperlink}
  • *
*

* So far, the ODT exporter has the known limitations of grid exporters. It * can work in batch mode and supports all types of exporter input and output as well as * font mappings. * * @see net.sf.jasperreports.export.OdtReportConfiguration * @author Teodor Danciu ([email protected]) */ public class JROdtExporter extends JRAbstractExporter { private static final Log log = LogFactory.getLog(JROdtExporter.class); /** * The exporter key, as used in * {@link GenericElementHandlerEnviroment#getElementHandler(JRGenericElementType, String)}. */ public static final String ODT_EXPORTER_KEY = JRPropertiesUtil.PROPERTY_PREFIX + "odt"; public static final String ODT_EXPORTER_PROPERTIES_PREFIX = JRPropertiesUtil.PROPERTY_PREFIX + "export.odt."; protected class ExporterContext extends BaseExporterContext implements JROdtExporterContext { TableBuilder tableBuilder = null; public ExporterContext(TableBuilder tableBuidler) { this.tableBuilder = tableBuidler; } @Override public TableBuilder getTableBuilder() { return tableBuilder; } } protected class OdtDocumentBuilder extends DocumentBuilder { public OdtDocumentBuilder(OasisZip oasisZip) { super(oasisZip); } @Override public JRStyledText getStyledText(JRPrintText text) { return JROdtExporter.this.getStyledText(text); } @Override public Locale getTextLocale(JRPrintText text) { return JROdtExporter.this.getTextLocale(text); } @Override public String getInvalidCharReplacement() { return JROdtExporter.this.invalidCharReplacement; } @Override protected void insertPageAnchor(TableBuilder tableBuilder) { JROdtExporter.this.insertPageAnchor(tableBuilder); } @Override protected JRHyperlinkProducer getHyperlinkProducer(JRPrintHyperlink link) { return JROdtExporter.this.getHyperlinkProducer(link); } @Override protected JasperReportsContext getJasperReportsContext() { return JROdtExporter.this.getJasperReportsContext(); } @Override protected int getReportIndex() { return JROdtExporter.this.reportIndex; } @Override protected int getPageIndex() { return JROdtExporter.this.pageIndex; } } /** * */ protected WriterHelper tempBodyWriter; protected WriterHelper tempStyleWriter; protected int reportIndex; protected int pageFormatIndex; protected int pageIndex; protected int tableIndex; protected boolean startPage; protected String invalidCharReplacement; protected LinkedList backcolorStack = new LinkedList<>(); protected Color backcolor; protected DocumentBuilder documentBuilder; protected StyleCache styleCache; protected ExporterNature nature; protected Map rowStyles = new HashMap<>(); protected Map columnStyles = new HashMap<>(); /** * @see #JROdtExporter(JasperReportsContext) */ public JROdtExporter() { this(DefaultJasperReportsContext.getInstance()); } /** * */ public JROdtExporter(JasperReportsContext jasperReportsContext) { super(jasperReportsContext); exporterContext = new ExporterContext(null); } @Override protected Class getConfigurationInterface() { return OdtExporterConfiguration.class; } @Override protected Class getItemConfigurationInterface() { return OdtReportConfiguration.class; } @Override @SuppressWarnings("deprecation") protected void ensureOutput() { if (exporterOutput == null) { exporterOutput = new net.sf.jasperreports.export.parameters.ParametersOutputStreamExporterOutput( getJasperReportsContext(), getParameters(), getCurrentJasperPrint() ); } } @Override public void exportReport() throws JRException { /* */ ensureJasperReportsContext(); ensureInput(); initExport(); ensureOutput(); OutputStream outputStream = getExporterOutput().getOutputStream(); try { exportReportToOasisZip(outputStream); } catch (IOException e) { throw new JRRuntimeException(e); } finally { getExporterOutput().close(); resetExportContext(); } } @Override protected void initExport() { super.initExport(); } @Override protected void initReport() { super.initReport(); if(jasperPrint.hasProperties() && jasperPrint.getPropertiesMap().containsProperty(JRXmlExporter.PROPERTY_REPLACE_INVALID_CHARS)) { // allows null values for the property invalidCharReplacement = jasperPrint.getProperty(JRXmlExporter.PROPERTY_REPLACE_INVALID_CHARS); } else { invalidCharReplacement = getPropertiesUtil().getProperty(JRXmlExporter.PROPERTY_REPLACE_INVALID_CHARS, jasperPrint); } nature = new JROdtExporterNature(getJasperReportsContext(), filter); } /** * */ protected void exportReportToOasisZip(OutputStream os) throws JRException, IOException { OasisZip oasisZip = new OdtZip(); ExportZipEntry tempBodyEntry = new FileBufferedZipEntry(null); ExportZipEntry tempStyleEntry = new FileBufferedZipEntry(null); tempBodyWriter = new WriterHelper(jasperReportsContext, tempBodyEntry.getWriter()); tempStyleWriter = new WriterHelper(jasperReportsContext, tempStyleEntry.getWriter()); documentBuilder = new OdtDocumentBuilder(oasisZip); styleCache = new StyleCache(jasperReportsContext, tempStyleWriter, getExporterKey()); WriterHelper stylesWriter = new WriterHelper(jasperReportsContext, oasisZip.getStylesEntry().getWriter()); List items = exporterInput.getItems(); StyleBuilder styleBuilder = new StyleBuilder(stylesWriter); styleBuilder.buildBeforeAutomaticStyles(jasperPrint); pageFormatIndex = -1; for(reportIndex = 0; reportIndex < items.size(); reportIndex++) { ExporterInputItem item = items.get(reportIndex); rowStyles.clear(); columnStyles.clear(); setCurrentExporterInputItem(item); List pages = jasperPrint.getPages(); if (pages != null && pages.size() > 0) { PageRange pageRange = getPageRange(); int startPageIndex = (pageRange == null || pageRange.getStartPageIndex() == null) ? 0 : pageRange.getStartPageIndex(); int endPageIndex = (pageRange == null || pageRange.getEndPageIndex() == null) ? (pages.size() - 1) : pageRange.getEndPageIndex(); PrintPageFormat oldPageFormat = null; JRPrintPage page = null; for(pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++) { if (Thread.interrupted()) { throw new ExportInterruptedException(); } PrintPageFormat pageFormat = jasperPrint.getPageFormat(pageIndex); if (oldPageFormat != pageFormat) { styleBuilder.buildPageLayout(++pageFormatIndex, pageFormat); oldPageFormat = pageFormat; } page = pages.get(pageIndex); exportPage(page); } } } styleBuilder.buildMasterPages(pageFormatIndex); stylesWriter.flush(); tempBodyWriter.flush(); tempStyleWriter.flush(); stylesWriter.close(); tempBodyWriter.close(); tempStyleWriter.close(); /* */ ContentBuilder contentBuilder = new ContentBuilder( oasisZip.getContentEntry(), tempStyleEntry, tempBodyEntry, styleCache.getFontFaces(), OasisZip.MIME_TYPE_ODT ); contentBuilder.build(); tempStyleEntry.dispose(); tempBodyEntry.dispose(); oasisZip.zipEntries(os); oasisZip.dispose(); } /** * */ protected void exportPage(JRPrintPage page) throws JRException, IOException { startPage = true; ReportExportConfiguration configuration = getCurrentItemConfiguration(); PrintPageFormat pageFormat = jasperPrint.getPageFormat(pageIndex); JRGridLayout layout = new JRGridLayout( nature, page.getElements(), pageFormat.getPageWidth(), pageFormat.getPageHeight(), configuration.getOffsetX() == null ? 0 : configuration.getOffsetX(), configuration.getOffsetY() == null ? 0 : configuration.getOffsetY(), null //address ); exportGrid(layout, null); JRExportProgressMonitor progressMonitor = configuration.getProgressMonitor(); if (progressMonitor != null) { progressMonitor.afterPageExport(); } } /** * */ protected void exportGrid(JRGridLayout gridLayout, JRPrintElementIndex frameIndex) throws IOException, JRException { boolean isFlexibleRowHeight = getCurrentItemConfiguration().isFlexibleRowHeight(); CutsInfo xCuts = gridLayout.getXCuts(); Grid grid = gridLayout.getGrid(); TableBuilder tableBuilder = frameIndex == null ? new TableBuilder(documentBuilder, jasperPrint, pageFormatIndex, pageIndex, tempBodyWriter, tempStyleWriter, styleCache, rowStyles, columnStyles) : new TableBuilder(documentBuilder, jasperPrint, frameIndex.toString(), tempBodyWriter, tempStyleWriter, styleCache, rowStyles, columnStyles); tableBuilder.buildTableStyle(gridLayout.getWidth()); tableBuilder.buildTableHeader(); for(int col = 1; col < xCuts.size(); col++) { tableBuilder.buildColumnStyle( col - 1, xCuts.getCutOffset(col) - xCuts.getCutOffset(col - 1) ); tableBuilder.buildColumnHeader(xCuts.getCutOffset(col) - xCuts.getCutOffset(col - 1)); tableBuilder.buildColumnFooter(); } int rowCount = grid.getRowCount(); for(int row = 0; row < rowCount; row++) { int emptyCellColSpan = 0; //int emptyCellWidth = 0; int rowHeight = gridLayout.getRowHeight(row); tableBuilder.buildRowStyle(row, isFlexibleRowHeight ? -1 : rowHeight); tableBuilder.buildRowHeader(isFlexibleRowHeight ? -1 : rowHeight); GridRow gridRow = grid.getRow(row); int rowSize = gridRow.size(); for(int col = 0; col < rowSize; col++) { JRExporterGridCell gridCell = gridRow.get(col); if (gridCell.getType() == JRExporterGridCell.TYPE_OCCUPIED_CELL) { if (emptyCellColSpan > 0) { //writeEmptyCell(gridCell, emptyCellColSpan, emptyCellWidth, rowHeight); emptyCellColSpan = 0; //emptyCellWidth = 0; } //writeOccupiedCells(1); exportOccupiedCells(1); // OccupiedGridCell occupiedGridCell = (OccupiedGridCell)gridCell; // ElementGridCell elementGridCell = (ElementGridCell)grid[occupiedGridCell.getRow()][occupiedGridCell.getCol()]; // exportOccupiedCells(elementGridCell); // col += elementGridCell.getColSpan() - 1; } else if(gridCell.getType() == JRExporterGridCell.TYPE_ELEMENT_CELL) { if (emptyCellColSpan > 0) { //writeEmptyCell(gridCell, emptyCellColSpan, emptyCellWidth, rowHeight); emptyCellColSpan = 0; //emptyCellWidth = 0; } JRPrintElement element = gridCell.getElement(); if (element instanceof JRPrintLine) { exportLine(tableBuilder, (JRPrintLine)element, gridCell); } else if (element instanceof JRPrintRectangle) { exportRectangle(tableBuilder, (JRPrintRectangle)element, gridCell); } else if (element instanceof JRPrintEllipse) { exportEllipse(tableBuilder, (JRPrintEllipse)element, gridCell); } else if (element instanceof JRPrintImage) { exportImage(tableBuilder, (JRPrintImage)element, gridCell); } else if (element instanceof JRPrintText) { exportText(tableBuilder, (JRPrintText)element, gridCell); } else if (element instanceof JRPrintFrame) { exportFrame(tableBuilder, (JRPrintFrame)element, gridCell); } else if (element instanceof JRGenericPrintElement) { exportGenericElement(tableBuilder, (JRGenericPrintElement)element, gridCell); } // //x += gridCell.colSpan - 1; //col += gridCell.getColSpan() - 1; } else { emptyCellColSpan++; //emptyCellWidth += gridCell.getWidth(); exportEmptyCell(gridCell, 1); } } // if (emptyCellColSpan > 0) // { // //writeEmptyCell(null, emptyCellColSpan, emptyCellWidth, rowHeight); // } tableBuilder.buildRowFooter(); } tableBuilder.buildTableFooter(); } /** * */ private void exportOccupiedCells(int count) { for(int i = 0; i < count; i++) { tempBodyWriter.write("\n"); } } /** * */ private void exportEmptyCell(JRExporterGridCell gridCell, int emptyCellColSpan) throws IOException { tempBodyWriter.write(" 1) { tempBodyWriter.write(" table:number-columns-spanned=\"" + emptyCellColSpan + "\""); } tempBodyWriter.write("/>\n"); exportOccupiedCells(emptyCellColSpan - 1); } /** * */ protected void exportFrame(TableBuilder tableBuilder, JRPrintFrame frame, JRExporterGridCell gridCell) throws IOException, JRException { tableBuilder.buildCellHeader(styleCache.getCellStyle(gridCell), gridCell.getColSpan(), gridCell.getRowSpan()); boolean appendBackcolor = frame.getModeValue() == ModeEnum.OPAQUE && (backcolor == null || frame.getBackcolor().getRGB() != backcolor.getRGB()); if (appendBackcolor) { setBackcolor(frame.getBackcolor()); } try { JRGridLayout layout = ((ElementGridCell) gridCell).getLayout(); JRPrintElementIndex frameIndex = new JRPrintElementIndex( reportIndex, pageIndex, gridCell.getElementAddress() ); exportGrid(layout, frameIndex); } finally { if (appendBackcolor) { restoreBackcolor(); } } tableBuilder.buildCellFooter(); } /** * */ protected void setBackcolor(Color color) { backcolorStack.addLast(backcolor); backcolor = color; } /** * */ protected void restoreBackcolor() { backcolor = backcolorStack.removeLast(); } /** * */ protected void exportRectangle(TableBuilder tableBuilder, JRPrintRectangle rectangle, JRExporterGridCell gridCell) { tableBuilder.exportRectangle(rectangle, gridCell); } /** * */ protected void exportLine(TableBuilder tableBuilder, JRPrintLine line, JRExporterGridCell gridCell) { tableBuilder.exportLine(line, gridCell); } /** * */ protected void exportEllipse(TableBuilder tableBuilder, JRPrintEllipse ellipse, JRExporterGridCell gridCell) { tableBuilder.exportEllipse(ellipse, gridCell); } /** * */ public void exportText(TableBuilder tableBuilder, JRPrintText text, JRExporterGridCell gridCell) { tableBuilder.exportText(text, gridCell, false, true, false); } /** * */ public void exportImage(TableBuilder tableBuilder, JRPrintImage image, JRExporterGridCell gridCell) throws JRException { int topPadding = Math.max(image.getLineBox().getTopPadding(), Math.round(image.getLineBox().getTopPen().getLineWidth())); int leftPadding = Math.max(image.getLineBox().getLeftPadding(), Math.round(image.getLineBox().getLeftPen().getLineWidth())); int bottomPadding = Math.max(image.getLineBox().getBottomPadding(), Math.round(image.getLineBox().getBottomPen().getLineWidth())); int rightPadding = Math.max(image.getLineBox().getRightPadding(), Math.round(image.getLineBox().getRightPen().getLineWidth())); int availableImageWidth = Math.max(0,image.getWidth() - leftPadding - rightPadding); int availableImageHeight = Math.max(0,image.getHeight() - topPadding - bottomPadding); tableBuilder.buildCellHeader(styleCache.getCellStyle(gridCell), gridCell.getColSpan(), gridCell.getRowSpan()); Renderable renderer = image.getRenderer(); if ( renderer != null && availableImageWidth > 0 && availableImageHeight > 0 ) { InternalImageProcessor imageProcessor = new InternalImageProcessor( image, gridCell, availableImageWidth, availableImageHeight ); InternalImageProcessorResult imageProcessorResult = null; try { imageProcessorResult = imageProcessor.process(renderer); } catch (Exception e) { Renderable onErrorRenderer = getRendererUtil().handleImageError(e, image.getOnErrorTypeValue()); if (onErrorRenderer != null) { imageProcessorResult = imageProcessor.process(onErrorRenderer); } } if (imageProcessorResult != null) { tempBodyWriter.write(""); documentBuilder.insertPageAnchor(tableBuilder); if (image.getAnchorName() != null) { tableBuilder.exportAnchor(JRStringUtil.xmlEncode(image.getAnchorName())); } boolean startedHyperlink = tableBuilder.startHyperlink(image,false); tempBodyWriter.write( "\n" ); tempBodyWriter.write("\n"); tempBodyWriter.write( "\n" ); tempBodyWriter.write("\n"); tempBodyWriter.write("\n"); tempBodyWriter.write("\n"); tempBodyWriter.write("\n"); if(startedHyperlink) { tableBuilder.endHyperlink(false); } tempBodyWriter.write(""); } } tableBuilder.buildCellFooter(); } private class InternalImageProcessor { private final JRPrintImage imageElement; private final RenderersCache imageRenderersCache; private final JRExporterGridCell cell; private final int availableImageWidth; private final int availableImageHeight; protected InternalImageProcessor( JRPrintImage imageElement, JRExporterGridCell cell, int availableImageWidth, int availableImageHeight ) { this.imageElement = imageElement; this.imageRenderersCache = imageElement.isUsingCache() ? documentBuilder.getRenderersCache() : new RenderersCache(getJasperReportsContext()); this.cell = cell; this.availableImageWidth = availableImageWidth; this.availableImageHeight = availableImageHeight; } private InternalImageProcessorResult process(Renderable renderer) throws JRException { // boolean isLazy = RendererUtil.isLazy(renderer); // // if (!isLazy) // { if (renderer instanceof ResourceRenderer) { renderer = imageRenderersCache.getLoadedRenderer((ResourceRenderer)renderer); } // } // check dimension first, to avoid caching renderers that might not be used eventually, due to their dimension errors ExifOrientationEnum exifOrientation = ExifOrientationEnum.NORMAL; if (renderer instanceof DataRenderable) { byte[] imageData = ((DataRenderable)renderer).getData(jasperReportsContext); exifOrientation = ImageUtil.getExifOrientation(imageData); } int imageWidth = availableImageWidth; int imageHeight = availableImageHeight; int xoffset = 0; int yoffset = 0; double cropTop = 0; double cropLeft = 0; double cropBottom = 0; double cropRight = 0; double angle = 0; switch (imageElement.getScaleImageValue()) { case FILL_FRAME : { switch (ImageUtil.getRotation(imageElement.getRotation(), exifOrientation)) { case LEFT: imageWidth = availableImageHeight; imageHeight = availableImageWidth; xoffset = (int)((availableImageWidth - availableImageHeight) / 2f); yoffset = - (int)((availableImageWidth - availableImageHeight) / 2f); angle = Math.PI / 2; break; case RIGHT: imageWidth = availableImageHeight; imageHeight = availableImageWidth; xoffset = (int)((availableImageWidth - availableImageHeight) / 2f); yoffset = - (int)((availableImageWidth - availableImageHeight) / 2f); angle = - Math.PI / 2; break; case UPSIDE_DOWN: imageWidth = availableImageWidth; imageHeight = availableImageHeight; xoffset = 0; yoffset = 0; angle = Math.PI; break; case NONE: default: imageWidth = availableImageWidth; imageHeight = availableImageHeight; xoffset = 0; yoffset = 0; angle = 0; break; } break; } case CLIP : { double normalWidth = availableImageWidth; double normalHeight = availableImageHeight; DimensionRenderable dimensionRenderer = imageRenderersCache.getDimensionRenderable(renderer); Dimension2D dimension = dimensionRenderer == null ? null : dimensionRenderer.getDimension(getJasperReportsContext()); if (dimension != null) { normalWidth = dimension.getWidth(); normalHeight = dimension.getHeight(); } switch (ImageUtil.getRotation(imageElement.getRotation(), exifOrientation)) { case LEFT: if (dimension == null) { normalWidth = availableImageHeight; normalHeight = availableImageWidth; } imageWidth = availableImageHeight; imageHeight = availableImageWidth; switch (imageElement.getHorizontalImageAlign()) { case RIGHT : cropLeft = normalWidth - availableImageHeight; cropRight = 0; yoffset = - (availableImageWidth - availableImageHeight) / 2 - (availableImageHeight - imageWidth); break; case CENTER : cropLeft = (normalWidth - availableImageHeight) / 2; cropRight = cropLeft; yoffset = - (availableImageWidth - availableImageHeight) / 2 - (availableImageHeight - imageWidth) / 2; break; case LEFT : default : cropLeft = 0; cropRight = normalWidth - availableImageHeight; yoffset = - (availableImageWidth - availableImageHeight) / 2; break; } switch (imageElement.getVerticalImageAlign()) { case TOP : cropTop = 0; cropBottom = normalHeight - availableImageWidth; xoffset = (availableImageWidth - availableImageHeight) / 2; break; case MIDDLE : cropTop = (normalHeight - availableImageWidth) / 2; cropBottom = cropTop; xoffset = (availableImageWidth - availableImageHeight) / 2 + (availableImageWidth - imageHeight) / 2; break; case BOTTOM : default : cropTop = normalHeight - availableImageWidth; cropBottom = 0; xoffset = (availableImageWidth - availableImageHeight) / 2 + availableImageWidth - imageHeight; break; } angle = Math.PI / 2; break; case RIGHT: if (dimension == null) { normalWidth = availableImageHeight; normalHeight = availableImageWidth; } imageWidth = availableImageHeight; imageHeight = availableImageWidth; switch (imageElement.getHorizontalImageAlign()) { case RIGHT : cropLeft = normalWidth - availableImageHeight; cropRight = 0; yoffset = - (availableImageWidth - availableImageHeight) / 2 + (availableImageHeight - imageWidth); break; case CENTER : cropLeft = (normalWidth - availableImageHeight) / 2; cropRight = cropLeft; yoffset = - (availableImageWidth - availableImageHeight) / 2 + (availableImageHeight - imageWidth) / 2; break; case LEFT : default : cropLeft = 0; cropRight = normalWidth - availableImageHeight; yoffset = - (availableImageWidth - availableImageHeight) / 2; break; } switch (imageElement.getVerticalImageAlign()) { case TOP : cropTop = 0; cropBottom = normalHeight - availableImageWidth; xoffset = (availableImageWidth - availableImageHeight) / 2; break; case MIDDLE : cropTop = (normalHeight - availableImageWidth) / 2; cropBottom = cropTop; xoffset = (availableImageWidth - availableImageHeight) / 2 - (availableImageWidth - imageHeight) / 2; break; case BOTTOM : default : cropTop = normalHeight - availableImageWidth; cropBottom = 0; xoffset = (availableImageWidth - availableImageHeight) / 2 - (availableImageWidth - imageHeight); break; } angle = - Math.PI / 2; break; case UPSIDE_DOWN: imageWidth = availableImageWidth; imageHeight = availableImageHeight; switch (imageElement.getHorizontalImageAlign()) { case RIGHT : cropLeft = normalWidth - availableImageWidth; cropRight = 0; xoffset = 0; break; case CENTER : cropLeft = (normalWidth - availableImageWidth) / 2; cropRight = cropLeft; xoffset = - (availableImageWidth - imageWidth) / 2; break; case LEFT : default : cropLeft = 0; cropRight = normalWidth - availableImageWidth; xoffset = - (availableImageWidth - imageWidth); break; } switch (imageElement.getVerticalImageAlign()) { case TOP : cropTop = 0; cropBottom = normalHeight - availableImageHeight; yoffset = 0; break; case MIDDLE : cropTop = (normalHeight - availableImageHeight) / 2; cropBottom = cropTop; yoffset = - (availableImageHeight - imageHeight) / 2; break; case BOTTOM : default : cropTop = normalHeight - availableImageHeight; cropBottom = 0; yoffset = - (availableImageHeight - imageHeight); break; } angle = Math.PI; break; case NONE: default: imageWidth = availableImageWidth; imageHeight = availableImageHeight; switch (imageElement.getHorizontalImageAlign()) { case RIGHT : cropLeft = normalWidth - availableImageWidth; cropRight = 0; xoffset = availableImageWidth - imageWidth; break; case CENTER : cropLeft = (normalWidth - availableImageWidth) / 2; cropRight = cropLeft; xoffset = (availableImageWidth - imageWidth) / 2; break; case LEFT : default : cropLeft = 0; cropRight = normalWidth - availableImageWidth; xoffset = 0; break; } switch (imageElement.getVerticalImageAlign()) { case TOP : cropTop = 0; cropBottom = normalHeight - availableImageHeight; yoffset = 0; break; case MIDDLE : cropTop = (normalHeight - availableImageHeight) / 2; cropBottom = cropTop; yoffset = (availableImageHeight - imageHeight) / 2; break; case BOTTOM : default : cropTop = normalHeight - availableImageHeight; cropBottom = 0; yoffset = availableImageHeight - imageHeight; break; } angle = 0; break; } Insets exifCrop = ImageUtil.getExifCrop(imageElement, exifOrientation, cropTop, cropLeft, cropBottom, cropRight); cropLeft = exifCrop.left; cropRight = exifCrop.right; cropTop = exifCrop.top; cropBottom = exifCrop.bottom; break; } case RETAIN_SHAPE : default : { double normalWidth = availableImageWidth; double normalHeight = availableImageHeight; Dimension2D dimension = null; // if (!isLazy) // { DimensionRenderable dimensionRenderer = imageRenderersCache.getDimensionRenderable(renderer); dimension = dimensionRenderer == null ? null : dimensionRenderer.getDimension(getJasperReportsContext()); if (dimension != null) { normalWidth = dimension.getWidth(); normalHeight = dimension.getHeight(); } // } double ratioX = 1f; double ratioY = 1f; switch (ImageUtil.getRotation(imageElement.getRotation(), exifOrientation)) { case LEFT: if (dimension == null) { normalWidth = availableImageHeight; normalHeight = availableImageWidth; } imageWidth = availableImageHeight; imageHeight = availableImageWidth; ratioX = availableImageWidth / normalHeight; ratioY = availableImageHeight / normalWidth; ratioX = ratioX < ratioY ? ratioX : ratioY; ratioY = ratioX; xoffset = (int)((availableImageWidth - availableImageHeight) / 2f); yoffset = - (int)((availableImageWidth - availableImageHeight) / 2f); cropLeft = (int)(ImageUtil.getXAlignFactor(imageElement) * (normalWidth - availableImageHeight / ratioX)); cropRight = (int)((1f - ImageUtil.getXAlignFactor(imageElement)) * (normalWidth - availableImageHeight / ratioX)); cropTop = (int)(ImageUtil.getYAlignFactor(imageElement) * (normalHeight - availableImageWidth / ratioY)); cropBottom = (int)((1f - ImageUtil.getYAlignFactor(imageElement)) * (normalHeight - availableImageWidth / ratioY)); angle = Math.PI / 2; break; case RIGHT: if (dimension == null) { normalWidth = availableImageHeight; normalHeight = availableImageWidth; } imageWidth = availableImageHeight; imageHeight = availableImageWidth; ratioX = availableImageWidth / normalHeight; ratioY = availableImageHeight / normalWidth; ratioX = ratioX < ratioY ? ratioX : ratioY; ratioY = ratioX; xoffset = (int)((availableImageWidth - availableImageHeight) / 2f); yoffset = - (int)((availableImageWidth - availableImageHeight) / 2f); cropLeft = (int)(ImageUtil.getXAlignFactor(imageElement) * (normalWidth - availableImageHeight / ratioX)); cropRight = (int)((1f - ImageUtil.getXAlignFactor(imageElement)) * (normalWidth - availableImageHeight / ratioX)); cropTop = (int)(ImageUtil.getYAlignFactor(imageElement) * (normalHeight - availableImageWidth / ratioY)); cropBottom = (int)((1f - ImageUtil.getYAlignFactor(imageElement)) * (normalHeight - availableImageWidth / ratioY)); angle = - Math.PI / 2; break; case UPSIDE_DOWN: imageWidth = availableImageWidth; imageHeight = availableImageHeight; ratioX = availableImageWidth / normalWidth; ratioY = availableImageHeight / normalHeight; ratioX = ratioX < ratioY ? ratioX : ratioY; ratioY = ratioX; xoffset = 0; yoffset = 0; cropLeft = (int)(ImageUtil.getXAlignFactor(imageElement) * (normalWidth - availableImageWidth / ratioX)); cropRight = (int)((1f - ImageUtil.getXAlignFactor(imageElement)) * (normalWidth - availableImageWidth / ratioX)); cropTop = (int)(ImageUtil.getYAlignFactor(imageElement) * (normalHeight - availableImageHeight / ratioY)); cropBottom = (int)((1f - ImageUtil.getYAlignFactor(imageElement)) * (normalHeight - availableImageHeight / ratioY)); angle = Math.PI; break; case NONE: default: imageWidth = availableImageWidth; imageHeight = availableImageHeight; ratioX = availableImageWidth / normalWidth; ratioY = availableImageHeight / normalHeight; ratioX = ratioX < ratioY ? ratioX : ratioY; ratioY = ratioX; xoffset = 0; yoffset = 0; cropLeft = (int)(ImageUtil.getXAlignFactor(imageElement) * (normalWidth - availableImageWidth / ratioX)); cropRight = (int)((1f - ImageUtil.getXAlignFactor(imageElement)) * (normalWidth - availableImageWidth / ratioX)); cropTop = (int)(ImageUtil.getYAlignFactor(imageElement) * (normalHeight - availableImageHeight / ratioY)); cropBottom = (int)((1f - ImageUtil.getYAlignFactor(imageElement)) * (normalHeight - availableImageHeight / ratioY)); angle = 0; break; } Insets exifCrop = ImageUtil.getExifCrop(imageElement, exifOrientation, cropTop, cropLeft, cropBottom, cropRight); cropLeft = exifCrop.left; cropRight = exifCrop.right; cropTop = exifCrop.top; cropBottom = exifCrop.bottom; } } String imagePath = documentBuilder.getImagePath( renderer, new Dimension(imageWidth, imageHeight), ModeEnum.OPAQUE == imageElement.getModeValue() ? imageElement.getBackcolor() : null, cell, // isLazy, imageRenderersCache ); return new InternalImageProcessorResult( imagePath, availableImageWidth, availableImageHeight, imageWidth, imageHeight, xoffset, yoffset, cropTop, cropLeft, cropBottom, cropRight, angle ); } } private class InternalImageProcessorResult { protected final String imagePath; protected final int frameWidth; protected final int frameHeight; protected final int imageWidth; protected final int imageHeight; protected final int xoffset; protected final int yoffset; protected final double cropTop; protected final double cropLeft; protected final double cropBottom; protected final double cropRight; protected final double angle; protected InternalImageProcessorResult( String imagePath, int frameWidth, int frameHeight, int imageWidth, int imageHeight, int xoffset, int yoffset, double cropTop, double cropLeft, double cropBottom, double cropRight, double angle ) { this.imagePath = imagePath; this.frameWidth = frameWidth; this.frameHeight = frameHeight; this.imageWidth = imageWidth; this.imageHeight = imageHeight; this.xoffset = xoffset; this.yoffset = yoffset; this.cropTop = cropTop; this.cropLeft = cropLeft; this.cropBottom = cropBottom; this.cropRight = cropRight; this.angle = angle; } } /** * */ protected void insertPageAnchor(TableBuilder tableBuilder) { if(startPage) { tableBuilder.exportAnchor(DocumentBuilder.JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + (pageIndex + 1)); startPage = false; } } /** * */ protected void exportGenericElement(TableBuilder tableBuilder, JRGenericPrintElement element, JRExporterGridCell gridCell) throws IOException, JRException { GenericElementOdtHandler handler = (GenericElementOdtHandler) GenericElementHandlerEnviroment.getInstance(getJasperReportsContext()).getElementHandler( element.getGenericType(), getExporterKey()); if (handler != null) { JROdtExporterContext exporterContext = new ExporterContext(tableBuilder); handler.exportElement(exporterContext, element, gridCell); } else { if (log.isDebugEnabled()) { log.debug("No ODT generic element handler for " + element.getGenericType()); } } } @Override public String getExporterKey() { return ODT_EXPORTER_KEY; } @Override public String getExporterPropertiesPrefix() { return ODT_EXPORTER_PROPERTIES_PREFIX; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy