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

net.sf.jasperreports.engine.export.ooxml.JRPptxExporter 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 .
 */
package net.sf.jasperreports.engine.export.ooxml;

import java.awt.Dimension;
import java.awt.geom.Dimension2D;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URLEncoder;
import java.text.AttributedCharacterIterator;
import java.text.AttributedCharacterIterator.Attribute;
import java.util.ArrayList;
import java.util.HashMap;
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.annotations.properties.Property;
import net.sf.jasperreports.annotations.properties.PropertyScope;
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.JRLineBox;
import net.sf.jasperreports.engine.JRPen;
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.JRStyle;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.base.JRBasePen;
import net.sf.jasperreports.engine.export.GenericElementHandlerEnviroment;
import net.sf.jasperreports.engine.export.HyperlinkUtil;
import net.sf.jasperreports.engine.export.JRExportProgressMonitor;
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.ooxml.type.PptxFieldTypeEnum;
import net.sf.jasperreports.engine.export.zip.ExportZipEntry;
import net.sf.jasperreports.engine.export.zip.FileBufferedZipEntry;
import net.sf.jasperreports.engine.type.BandTypeEnum;
import net.sf.jasperreports.engine.type.LineDirectionEnum;
import net.sf.jasperreports.engine.type.LineStyleEnum;
import net.sf.jasperreports.engine.type.ModeEnum;
import net.sf.jasperreports.engine.type.RotationEnum;
import net.sf.jasperreports.engine.type.ScaleImageEnum;
import net.sf.jasperreports.engine.util.ExifOrientationEnum;
import net.sf.jasperreports.engine.util.FileBufferedWriter;
import net.sf.jasperreports.engine.util.ImageUtil;
import net.sf.jasperreports.engine.util.ImageUtil.Insets;
import net.sf.jasperreports.engine.util.JRColorUtil;
import net.sf.jasperreports.engine.util.JRStyledText;
import net.sf.jasperreports.engine.util.JRStyledTextUtil;
import net.sf.jasperreports.engine.util.JRTypeSniffer;
import net.sf.jasperreports.engine.util.Pair;
import net.sf.jasperreports.engine.util.StyledTextWriteContext;
import net.sf.jasperreports.export.ExportInterruptedException;
import net.sf.jasperreports.export.ExporterInputItem;
import net.sf.jasperreports.export.OutputStreamExporterOutput;
import net.sf.jasperreports.export.PptxExporterConfiguration;
import net.sf.jasperreports.export.PptxReportConfiguration;
import net.sf.jasperreports.properties.PropertyConstants;
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 Microsoft PowerPoint 2007 format (PPTX).
 * 

* This exporter uses an absolute positioned layout and currently there is a single special * configuration that can be applied to a PPTX * exporter instance (see {@link net.sf.jasperreports.export.PptxReportConfiguration}) * to configure its behavior: one can ignore hyperlinks in generated documents if they are * not intended for the PPTX output format. This can be customized using either the * {@link net.sf.jasperreports.export.PptxReportConfiguration#isIgnoreHyperlink() isIgnoreHyperlink()} * exporter configuration flag, or its corresponding exporter hint called * {@link net.sf.jasperreports.export.PptxReportConfiguration#PROPERTY_IGNORE_HYPERLINK net.sf.jasperreports.export.pptx.ignore.hyperlink}. *

* It supports font mappings, batch mode exporting, and filtering * out content using exporter filters. *

* Documents produced using this exporter can be generated in the great majority of the * samples shipped with the JasperReports project source files, where the pptx Ant task is * defined. * * @see net.sf.jasperreports.export.PptxReportConfiguration * @author Teodor Danciu ([email protected]) */ public class JRPptxExporter extends JRAbstractExporter { private static final Log log = LogFactory.getLog(JRPptxExporter.class); /** * The exporter key, as used in * {@link GenericElementHandlerEnviroment#getElementHandler(JRGenericElementType, String)}. */ public static final String PPTX_EXPORTER_KEY = JRPropertiesUtil.PROPERTY_PREFIX + "pptx"; public static final String PPTX_EXPORTER_PROPERTIES_PREFIX = JRPropertiesUtil.PROPERTY_PREFIX + "export.pptx."; /** * Property that specifies if this element, when found on the first page of the document, should be exported into the slide master, * and then ignored on all pages/slides. */ @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.TEXT_ELEMENT}, valueType = Boolean.class, defaultValue = PropertyConstants.BOOLEAN_FALSE, sinceVersion = PropertyConstants.VERSION_6_8_0 ) public static final String PROPERTY_TO_SLIDE_MASTER = PPTX_EXPORTER_PROPERTIES_PREFIX + "to.slide.master"; /** * Property that specifies the field type associated with this element in the PPTX export. * When this property is set, the element value will be automatically updated when the presentation is open. *

    *
  • slidenum - the current slide number will be displayed in this field
  • *
  • datetime - the current date/time will be displayed in this field, according to some predefined patterns: *
      *
    1. MM/dd/yyyy
    2. *
    3. EEEE, MMMM dd, yyyy
    4. *
    5. dd MMMM yyyy
    6. *
    7. MMMM dd, yyyy
    8. *
    9. dd-MMM-yy
    10. *
    11. MMMM yy
    12. *
    13. MMM-yy
    14. *
    15. MM/dd/yyyy hh:mm a
    16. *
    17. MM/dd/yyyy hh:mm:ss a
    18. *
    19. HH:mm
    20. *
    21. HH:mm:ss
    22. *
    23. hh:mm a
    24. *
    25. hh:mm:ss a
    26. *
    * If none of the above patterns are set for the element, the date/time will be displayed using the default pattern of the PPTX viewer. *
  • *
      */ @Property( category = PropertyConstants.CATEGORY_EXPORT, scopes = {PropertyScope.TEXT_ELEMENT}, sinceVersion = PropertyConstants.VERSION_6_8_0 ) public static final String PROPERTY_FIELD_TYPE = PPTX_EXPORTER_PROPERTIES_PREFIX + "field.type"; public static final String FIELD_TYPE_SLIDENUM = "slidenum"; public static final String FIELD_TYPE_DATETIME = "datetime"; /** * */ protected static final String JR_PAGE_ANCHOR_PREFIX = "JR_PAGE_ANCHOR_"; /** * */ public static final String IMAGE_NAME_PREFIX = "img_"; protected static final int IMAGE_NAME_PREFIX_LEGTH = IMAGE_NAME_PREFIX.length(); /** * */ protected PptxZip pptxZip; protected PptxFontHelper fontHelper; protected PptxPresentationHelper presentationHelper; protected PptxPresentationRelsHelper presentationRelsHelper; protected PptxContentTypesHelper ctHelper; protected PropsAppHelper appHelper; protected PropsCoreHelper coreHelper; protected PptxSlideHelper slideHelper; protected PptxSlideRelsHelper slideRelsHelper; protected Writer presentationWriter; protected Writer presentationRelsWriter; protected Map> rendererToImagePathMap; protected RenderersCache renderersCache; // protected Map imageMaps; // protected Map hyperlinksMap; protected int reportIndex; protected int pageIndex; protected List frameIndexStack; protected int elementIndex; protected boolean startPage; protected String invalidCharReplacement; /** * used for counting the total number of sheets */ protected int slideIndex; private PptxRunHelper runHelper; protected class ExporterContext extends BaseExporterContext implements JRPptxExporterContext { } /** * @see #JRPptxExporter(JasperReportsContext) */ public JRPptxExporter() { this(DefaultJasperReportsContext.getInstance()); } /** * */ public JRPptxExporter(JasperReportsContext jasperReportsContext) { super(jasperReportsContext); exporterContext = new ExporterContext(); } @Override protected Class getConfigurationInterface() { return PptxExporterConfiguration.class; } @Override protected Class getItemConfigurationInterface() { return PptxReportConfiguration.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(); rendererToImagePathMap = new HashMap<>(); // imageMaps = new HashMap(); // hyperlinksMap = new HashMap(); initExport(); ensureOutput(); OutputStream outputStream = getExporterOutput().getOutputStream(); try { exportReportToStream(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); } renderersCache = new RenderersCache(getJasperReportsContext()); } /** * */ protected void exportReportToStream(OutputStream os) throws JRException, IOException { pptxZip = new PptxZip(); PptxExporterConfiguration configuration = getCurrentConfiguration(); presentationWriter = pptxZip.getPresentationEntry().getWriter(); presentationRelsWriter = pptxZip.getRelsEntry().getWriter(); boolean isEmbedFonts = Boolean.TRUE.equals(configuration.isEmbedFonts()); FileBufferedWriter fontWriter = new FileBufferedWriter(); fontHelper = new PptxFontHelper( jasperReportsContext, fontWriter, presentationRelsWriter, pptxZip, isEmbedFonts ); presentationHelper = new PptxPresentationHelper(jasperReportsContext, presentationWriter, fontWriter); presentationHelper.exportHeader(isEmbedFonts); presentationRelsHelper = new PptxPresentationRelsHelper(jasperReportsContext, presentationRelsWriter); presentationRelsHelper.exportHeader(); ctHelper = new PptxContentTypesHelper(jasperReportsContext, pptxZip.getContentTypesEntry().getWriter()); ctHelper.exportHeader(); appHelper = new PropsAppHelper(jasperReportsContext, pptxZip.getAppEntry().getWriter()); coreHelper = new PropsCoreHelper(jasperReportsContext, pptxZip.getCoreEntry().getWriter()); appHelper.exportHeader(); String application = configuration.getMetadataApplication(); if( application == null ) { application = "JasperReports Library version " + Package.getPackage("net.sf.jasperreports.engine").getImplementationVersion(); } appHelper.exportProperty(PropsAppHelper.PROPERTY_APPLICATION, application); coreHelper.exportHeader(); String title = configuration.getMetadataTitle(); if (title != null) { coreHelper.exportProperty(PropsCoreHelper.PROPERTY_TITLE, title); } String subject = configuration.getMetadataSubject(); if (subject != null) { coreHelper.exportProperty(PropsCoreHelper.PROPERTY_SUBJECT, subject); } String author = configuration.getMetadataAuthor(); if (author != null) { coreHelper.exportProperty(PropsCoreHelper.PROPERTY_CREATOR, author); } String keywords = configuration.getMetadataKeywords(); if (keywords != null) { coreHelper.exportProperty(PropsCoreHelper.PROPERTY_KEYWORDS, keywords); } Integer slideMasterReport = configuration.getSlideMasterReport(); if (slideMasterReport == null) { slideMasterReport = 1; } int slideMasterReportIndex = slideMasterReport - 1; Integer slideMasterPage = configuration.getSlideMasterPage(); if (slideMasterPage == null) { slideMasterPage = 1; } int slideMasterPageIndex = slideMasterPage - 1; // DocxStyleHelper styleHelper = // new DocxStyleHelper( // null,//pptxZip.getStylesEntry().getWriter(), // fontMap, // getExporterKey() // ); // styleHelper.export(jasperPrintList); // styleHelper.close(); List items = exporterInput.getItems(); boolean hasSlideMasterElements = false; createSlideMaster(); if ( 0 <= slideMasterReportIndex && slideMasterReportIndex < items.size() ) { if (Thread.interrupted()) { throw new ExportInterruptedException(); } ExporterInputItem item = items.get(slideMasterReportIndex); 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(); if ( startPageIndex <= slideMasterPageIndex && slideMasterPageIndex <= endPageIndex ) { hasSlideMasterElements = exportPageToSlideMaster(pages.get(slideMasterPageIndex), configuration.isBackgroundAsSlideMaster()); } } } closeSlideMaster(); for (reportIndex = 0; reportIndex < items.size(); reportIndex++) { ExporterInputItem item = items.get(reportIndex); 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(); net.sf.jasperreports.engine.util.PageRange[] hideSmPageRanges = null; String hideSlideMasterPages = getCurrentItemConfiguration().getHideSlideMasterPages(); if (hideSlideMasterPages != null && hideSlideMasterPages.trim().length() > 0) { hideSmPageRanges = net.sf.jasperreports.engine.util.PageRange.parse(hideSlideMasterPages); } for (pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++) { if (Thread.interrupted()) { throw new ExportInterruptedException(); } JRPrintPage page = pages.get(pageIndex); createSlide(net.sf.jasperreports.engine.util.PageRange.isPageInRanges(pageIndex + 1, hideSmPageRanges)); slideIndex++; exportPage(page, configuration.isBackgroundAsSlideMaster(), hasSlideMasterElements); closeSlide(); } } } fontHelper.exportFonts(); fontWriter.close(); presentationHelper.exportFooter(jasperPrint); presentationHelper.close(); // if ((hyperlinksMap != null && hyperlinksMap.size() > 0)) // { // for(Iterator it = hyperlinksMap.keySet().iterator(); it.hasNext();) // { // String href = (String)it.next(); // String id = (String)hyperlinksMap.get(href); // // relsHelper.exportHyperlink(id, href); // } // } presentationRelsHelper.exportFooter(); presentationRelsHelper.close(); ctHelper.exportFooter(); ctHelper.close(); appHelper.exportFooter(); appHelper.close(); coreHelper.exportFooter(); coreHelper.close(); pptxZip.zipEntries(os); fontWriter.dispose(); pptxZip.dispose(); } /** * */ protected boolean exportPageToSlideMaster(JRPrintPage page, boolean isBackgroundAsSlideMaster) throws JRException { frameIndexStack = new ArrayList<>(); boolean hasSlideMasterElements = false; List elements = page.getElements(); if (elements != null && elements.size() > 0) { for (int i = 0; i < elements.size(); i++) { JRPrintElement element = elements.get(i); elementIndex = i; if ( (isBackgroundAsSlideMaster && element.getOrigin().getBandTypeValue() == BandTypeEnum.BACKGROUND) || getPropertiesUtil().getBooleanProperty(element, PROPERTY_TO_SLIDE_MASTER, false) ) { if (filter == null || filter.isToExport(element)) { exportElement(element); hasSlideMasterElements = true; } } } } return hasSlideMasterElements; } /** * */ protected void exportPage(JRPrintPage page, boolean isBackgroundAsSlideMaster, boolean hasToSlideMasterElements) throws JRException { frameIndexStack = new ArrayList<>(); List elements = page.getElements(); if (elements != null && elements.size() > 0) { for (int i = 0; i < elements.size(); i++) { JRPrintElement element = elements.get(i); elementIndex = i; if ( !(isBackgroundAsSlideMaster && element.getOrigin().getBandTypeValue() == BandTypeEnum.BACKGROUND) && !(hasToSlideMasterElements && getPropertiesUtil().getBooleanProperty(element, PROPERTY_TO_SLIDE_MASTER, false)) ) { if (filter == null || filter.isToExport(element)) { exportElement(element); } } } } JRExportProgressMonitor progressMonitor = getCurrentItemConfiguration().getProgressMonitor(); if (progressMonitor != null) { progressMonitor.afterPageExport(); } } protected void createSlideMaster() { ExportZipEntry slideMasterRelsEntry = pptxZip.addSlideMasterRels(); Writer slideMasterRelsWriter = slideMasterRelsEntry.getWriter(); slideRelsHelper = new PptxSlideRelsHelper(jasperReportsContext, slideMasterRelsWriter); ExportZipEntry slideMasterEntry = pptxZip.addSlideMaster(); Writer slideMasterWriter = slideMasterEntry.getWriter(); slideHelper = new PptxSlideHelper(jasperReportsContext, slideMasterWriter, slideRelsHelper); // cellHelper = new XlsxCellHelper(sheetWriter, styleHelper); // runHelper = new PptxRunHelper(jasperReportsContext, slideMasterWriter, fontHelper); slideHelper.exportHeader(true, false); slideRelsHelper.exportHeader(true); } protected void createSlide(boolean hideSlideMaster) { presentationHelper.exportSlide(slideIndex + 1); ctHelper.exportSlide(slideIndex + 1); presentationRelsHelper.exportSlide(slideIndex + 1); // pptxZip.addEntry("ppt/slides/_rels/slide" + (slideIndex + 1) + ".xml.rels", "net/sf/jasperreports/engine/export/ooxml/pptx/ppt/slides/_rels/slide1.xml.rels"); ExportZipEntry slideRelsEntry = pptxZip.addSlideRels(slideIndex + 1); Writer slideRelsWriter = slideRelsEntry.getWriter(); slideRelsHelper = new PptxSlideRelsHelper(jasperReportsContext, slideRelsWriter); ExportZipEntry slideEntry = pptxZip.addSlide(slideIndex + 1); Writer slideWriter = slideEntry.getWriter(); slideHelper = new PptxSlideHelper(jasperReportsContext, slideWriter, slideRelsHelper); // cellHelper = new XlsxCellHelper(sheetWriter, styleHelper); // runHelper = new PptxRunHelper(jasperReportsContext, slideWriter, fontHelper); slideHelper.exportHeader(false, hideSlideMaster); slideRelsHelper.exportHeader(false); } protected void closeSlideMaster() { if (slideHelper != null) { slideHelper.exportFooter(true); slideHelper.close(); slideRelsHelper.exportFooter(); slideRelsHelper.close(); } } protected void closeSlide() { if (slideHelper != null) { slideHelper.exportFooter(false); slideHelper.close(); slideRelsHelper.exportFooter(); slideRelsHelper.close(); } } /** * */ protected void exportElement(JRPrintElement element) throws JRException { if (element instanceof JRPrintLine) { exportLine((JRPrintLine)element); } else if (element instanceof JRPrintRectangle) { exportRectangle((JRPrintRectangle)element); } else if (element instanceof JRPrintEllipse) { exportEllipse((JRPrintEllipse)element); } else if (element instanceof JRPrintImage) { exportImage((JRPrintImage)element); } else if (element instanceof JRPrintText) { exportText((JRPrintText)element); } else if (element instanceof JRPrintFrame) { exportFrame((JRPrintFrame)element); } else if (element instanceof JRGenericPrintElement) { exportGenericElement((JRGenericPrintElement) element); } } /** * */ protected void exportLine(JRPrintLine line) { int x = line.getX() + getOffsetX(); int y = line.getY() + getOffsetY(); int height = line.getHeight(); int width = line.getWidth(); if (width <= 1 || height <= 1) { if (width > 1) { height = 0; } else { width = 0; } } slideHelper.write("\n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); if (line.getModeValue() == ModeEnum.OPAQUE && line.getBackcolor() != null) { slideHelper.write("\n"); } exportPen(line.getLinePen()); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write("\n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write("\n"); } /** * */ protected void exportPen(JRPen pen) { if (pen != null && pen.getLineWidth() > 0) { slideHelper.write(" \n"); slideHelper.write("\n"); slideHelper.write("\n"); slideHelper.write(" \n"); } } /** * */ protected void exportRectangle(JRPrintRectangle rectangle) { exportRectangle(rectangle, rectangle.getLinePen(), rectangle.getRadius()); } /** * */ protected void exportRectangle(JRPrintElement rectangle, JRPen pen, int radius) { slideHelper.write("\n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" "); if(radius > 0) { // a rounded rectangle radius cannot exceed 1/2 of its lower side; int size = Math.min(50000, (radius * 100000)/Math.min(rectangle.getHeight(), rectangle.getWidth())); slideHelper.write("\n"); } else { slideHelper.write("\n"); } if (rectangle.getModeValue() == ModeEnum.OPAQUE && rectangle.getBackcolor() != null) { slideHelper.write("\n"); } exportPen(pen); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write("\n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write("\n"); } /** * */ protected void exportEllipse(JRPrintEllipse ellipse) { slideHelper.write("\n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); if (ellipse.getModeValue() == ModeEnum.OPAQUE && ellipse.getBackcolor() != null) { slideHelper.write("\n"); } exportPen(ellipse.getLinePen()); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write("\n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write("\n"); } /** * */ public void exportText(JRPrintText text) { JRStyledText styledText = getStyledText(text); int textLength = 0; if (styledText != null) { textLength = styledText.length(); } int x = 0; int y = 0; int width = 0; int height = 0; int rotation = 0; int leftPadding = text.getLineBox().getLeftPadding(); int topPadding = text.getLineBox().getTopPadding(); int rightPadding = text.getLineBox().getRightPadding(); int bottomPadding = text.getLineBox().getBottomPadding(); switch (text.getRotationValue()) { case LEFT: { rotation = -5400000; x = text.getX() + getOffsetX() - (text.getHeight() - text.getWidth()) / 2; y = text.getY() + getOffsetY() + (text.getHeight() - text.getWidth()) / 2; width = text.getHeight(); height = text.getWidth(); int tmpPadding = topPadding; topPadding = leftPadding; leftPadding = bottomPadding; bottomPadding = rightPadding; rightPadding = tmpPadding; break; } case RIGHT: { rotation = 5400000; x = text.getX() + getOffsetX() - (text.getHeight() - text.getWidth()) / 2; y = text.getY() + getOffsetY() + (text.getHeight() - text.getWidth()) / 2; width = text.getHeight(); height = text.getWidth(); int tmpPadding = topPadding; topPadding = rightPadding; rightPadding = bottomPadding; bottomPadding = leftPadding; leftPadding = tmpPadding; break; } case UPSIDE_DOWN: { rotation = 10800000; x = text.getX() + getOffsetX(); y = text.getY() + getOffsetY(); width = text.getWidth(); height = text.getHeight(); int tmpPadding = topPadding; topPadding = bottomPadding; bottomPadding = tmpPadding; tmpPadding = leftPadding; leftPadding = rightPadding; rightPadding = tmpPadding; break; } case NONE: default: { rotation = 0; x = text.getX() + getOffsetX(); y = text.getY() + getOffsetY(); width = text.getWidth(); height = text.getHeight(); break; } } slideHelper.write("\n"); slideHelper.write(" \n"); slideHelper.write(" \n"); String href = getHyperlinkURL(text); if (href != null) { slideHelper.exportHyperlink(href); } slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); if (text.getModeValue() == ModeEnum.OPAQUE && text.getBackcolor() != null) { slideHelper.write("\n"); } exportPen(text.getLineBox()); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); // if (styleBuffer.length() > 0) // { // writer.write(" style=\""); // writer.write(styleBuffer.toString()); // writer.write("\""); // } // // writer.write(">"); slideHelper.write(" \n"); slideHelper.write("\n"); slideHelper.write("\n"); runHelper.exportProps(text, getTextLocale(text)); slideHelper.write("\n"); // insertPageAnchor(); // if (text.getAnchorName() != null) // { // tempBodyWriter.write(""); // } // boolean startedHyperlink = startHyperlink(text, true); if (textLength > 0) { PptxFieldTypeEnum fieldTypeEnum = PptxFieldTypeEnum.getByName(JRPropertiesUtil.getOwnProperty(text, PROPERTY_FIELD_TYPE)); String uuid = null; String fieldType = null; if (fieldTypeEnum != null) { uuid = text.getUUID().toString().toUpperCase(); fieldType = fieldTypeEnum.getName(); } exportStyledText(text.getStyle(), styledText, getTextLocale(text), fieldType, uuid); } // if (startedHyperlink) // { // endHyperlink(true); // } slideHelper.write(" \n"); // docHelper.write(" \n"); // docHelper.flush(); slideHelper.write(" \n"); slideHelper.write("\n"); } /** * */ protected void exportPen(JRLineBox lineBox) { exportPen(getPptxPen(lineBox)); } /** * */ protected void exportStyledText(JRStyle style, JRStyledText styledText, Locale locale, String fieldType, String uuid) { StyledTextWriteContext context = new StyledTextWriteContext(); String allText = styledText.getText(); int runLimit = 0; AttributedCharacterIterator iterator = styledText.getAttributedString().getIterator(); while (runLimit < styledText.length() && (runLimit = iterator.getRunLimit()) <= styledText.length()) { Map attributes = iterator.getAttributes(); String runText = allText.substring(iterator.getIndex(), runLimit); context.next(attributes, runText); if (context.listItemStartsWithNewLine() && !context.isListItemStart() && (context.isListItemEnd() || context.isListStart() || context.isListEnd())) { runText = runText.substring(1); } if (runText.length() > 0) { String bulletText = JRStyledTextUtil.getIndentedBulletText(context); String text = (bulletText == null ? "" : bulletText) + runText; if (fieldType != null) { runHelper.export( style, attributes, text, locale, invalidCharReplacement, fieldType, uuid ); } else { runHelper.export( style, attributes, text, locale, invalidCharReplacement ); } } iterator.setIndex(runLimit); } } /** * */ public void exportImage(JRPrintImage image) throws JRException { int leftPadding = image.getLineBox().getLeftPadding(); int topPadding = image.getLineBox().getTopPadding();//FIXMEDOCX maybe consider border thickness int rightPadding = image.getLineBox().getRightPadding(); int bottomPadding = image.getLineBox().getBottomPadding(); JRPen pen = getPptxPen(image.getLineBox()); boolean hasPadding = (leftPadding + topPadding + rightPadding + bottomPadding) > 0; if (hasPadding) { exportRectangle(image, pen, 0); } int availableImageWidth = image.getWidth() - leftPadding - rightPadding; availableImageWidth = availableImageWidth < 0 ? 0 : availableImageWidth; int availableImageHeight = image.getHeight() - topPadding - bottomPadding; availableImageHeight = availableImageHeight < 0 ? 0 : availableImageHeight; Renderable renderer = image.getRenderer(); if ( renderer != null && availableImageWidth > 0 && availableImageHeight > 0 ) { InternalImageProcessor imageProcessor = new InternalImageProcessor( image, 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)//FIXMEPPTX render background for null images, like other exporters do { int renderWidth = availableImageWidth; int renderHeight = availableImageHeight; int xoffset = 0; int yoffset = 0; double cropTop = 0; double cropLeft = 0; double cropBottom = 0; double cropRight = 0; int angle = 0; switch (image.getScaleImageValue()) { case FILL_FRAME : { switch (ImageUtil.getRotation(image.getRotation(), imageProcessorResult.exifOrientation)) { case LEFT: renderWidth = availableImageHeight; renderHeight = availableImageWidth; xoffset = (availableImageWidth - availableImageHeight) / 2; yoffset = - (availableImageWidth - availableImageHeight) / 2; angle = -90; break; case RIGHT: renderWidth = availableImageHeight; renderHeight = availableImageWidth; xoffset = (availableImageWidth - availableImageHeight) / 2; yoffset = - (availableImageWidth - availableImageHeight) / 2; angle = 90; break; case UPSIDE_DOWN: renderWidth = availableImageWidth; renderHeight = availableImageHeight; angle = 180; break; case NONE: default: renderWidth = availableImageWidth; renderHeight = availableImageHeight; angle = 0; break; } break; } case CLIP : { double normalWidth = availableImageWidth; double normalHeight = availableImageHeight; Dimension2D dimension = imageProcessorResult.dimension; if (dimension != null) { normalWidth = dimension.getWidth(); normalHeight = dimension.getHeight(); } switch (ImageUtil.getRotation(image.getRotation(), imageProcessorResult.exifOrientation)) { case LEFT: if (dimension == null) { normalWidth = availableImageHeight; normalHeight = availableImageWidth; } renderWidth = availableImageHeight; renderHeight = availableImageWidth; xoffset = (availableImageWidth - availableImageHeight) / 2; yoffset = - (availableImageWidth - availableImageHeight) / 2; cropLeft = ImageUtil.getXAlignFactor(image) * (availableImageHeight - normalWidth) / availableImageHeight; cropRight = (1f - ImageUtil.getXAlignFactor(image)) * (availableImageHeight - normalWidth) / availableImageHeight; cropTop = ImageUtil.getYAlignFactor(image) * (availableImageWidth - normalHeight) / availableImageWidth; cropBottom = (1f - ImageUtil.getYAlignFactor(image)) * (availableImageWidth - normalHeight) / availableImageWidth; angle = -90; break; case RIGHT: if (dimension == null) { normalWidth = availableImageHeight; normalHeight = availableImageWidth; } renderWidth = availableImageHeight; renderHeight = availableImageWidth; xoffset = (availableImageWidth - availableImageHeight) / 2; yoffset = - (availableImageWidth - availableImageHeight) / 2; cropLeft = ImageUtil.getXAlignFactor(image) * (availableImageHeight - normalWidth) / availableImageHeight; cropRight = (1f - ImageUtil.getXAlignFactor(image)) * (availableImageHeight - normalWidth) / availableImageHeight; cropTop = ImageUtil.getYAlignFactor(image) * (availableImageWidth - normalHeight) / availableImageWidth; cropBottom = (1f - ImageUtil.getYAlignFactor(image)) * (availableImageWidth - normalHeight) / availableImageWidth; angle = 90; break; case UPSIDE_DOWN: cropLeft = ImageUtil.getXAlignFactor(image) * (availableImageWidth - normalWidth) / availableImageWidth; cropRight = (1f - ImageUtil.getXAlignFactor(image)) * (availableImageWidth - normalWidth) / availableImageWidth; cropTop = ImageUtil.getYAlignFactor(image) * (availableImageHeight - normalHeight) / availableImageHeight; cropBottom = (1f - ImageUtil.getYAlignFactor(image)) * (availableImageHeight - normalHeight) / availableImageHeight; angle = 180; break; case NONE: default: cropLeft = ImageUtil.getXAlignFactor(image) * (availableImageWidth - normalWidth) / availableImageWidth; cropRight = (1f - ImageUtil.getXAlignFactor(image)) * (availableImageWidth - normalWidth) / availableImageWidth; cropTop = ImageUtil.getYAlignFactor(image) * (availableImageHeight - normalHeight) / availableImageHeight; cropBottom = (1f - ImageUtil.getYAlignFactor(image)) * (availableImageHeight - normalHeight) / availableImageHeight; angle = 0; break; } Insets exifCrop = ImageUtil.getExifCrop(image, imageProcessorResult.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 = imageProcessorResult.dimension; if (dimension != null) { normalWidth = dimension.getWidth(); normalHeight = dimension.getHeight(); } double ratioX = 1d; double ratioY = 1d; double imageWidth = availableImageWidth; double imageHeight = availableImageHeight; switch (ImageUtil.getRotation(image.getRotation(), imageProcessorResult.exifOrientation)) { case LEFT: if (dimension == null) { normalWidth = availableImageHeight; normalHeight = availableImageWidth; } renderWidth = availableImageHeight; renderHeight = availableImageWidth; ratioX = availableImageWidth / normalHeight; ratioY = availableImageHeight / normalWidth; ratioX = ratioX < ratioY ? ratioX : ratioY; ratioY = ratioX; imageWidth = (int)(normalHeight * ratioX); imageHeight = (int)(normalWidth * ratioY); xoffset = (availableImageWidth - availableImageHeight) / 2; yoffset = - (availableImageWidth - availableImageHeight) / 2; cropLeft = ImageUtil.getXAlignFactor(image) * (availableImageHeight - imageHeight) / availableImageHeight; cropRight = (1f - ImageUtil.getXAlignFactor(image)) * (availableImageHeight - imageHeight) / availableImageHeight; cropTop = ImageUtil.getYAlignFactor(image) * (availableImageWidth - imageWidth) / availableImageWidth; cropBottom = (1f - ImageUtil.getYAlignFactor(image)) * (availableImageWidth - imageWidth) / availableImageWidth; angle = -90; break; case RIGHT: if (dimension == null) { normalWidth = availableImageHeight; normalHeight = availableImageWidth; } renderWidth = availableImageHeight; renderHeight = availableImageWidth; ratioX = availableImageWidth / normalHeight; ratioY = availableImageHeight / normalWidth; ratioX = ratioX < ratioY ? ratioX : ratioY; ratioY = ratioX; imageWidth = (int)(normalHeight * ratioX); imageHeight = (int)(normalWidth * ratioY); xoffset = (availableImageWidth - availableImageHeight) / 2; yoffset = - (availableImageWidth - availableImageHeight) / 2; cropLeft = ImageUtil.getXAlignFactor(image) * (availableImageHeight - imageHeight) / availableImageHeight; cropRight = (1f - ImageUtil.getXAlignFactor(image)) * (availableImageHeight - imageHeight) / availableImageHeight; cropTop = ImageUtil.getYAlignFactor(image) * (availableImageWidth - imageWidth) / availableImageWidth; cropBottom = (1f - ImageUtil.getYAlignFactor(image)) * (availableImageWidth - imageWidth) / availableImageWidth; angle = 90; break; case UPSIDE_DOWN: renderWidth = availableImageWidth; renderHeight = availableImageHeight; ratioX = availableImageWidth / normalWidth; ratioY = availableImageHeight / normalHeight; ratioX = ratioX < ratioY ? ratioX : ratioY; ratioY = ratioX; imageWidth = (int)(normalWidth * ratioX); imageHeight = (int)(normalHeight * ratioY); cropLeft = ImageUtil.getXAlignFactor(image) * (availableImageWidth - imageWidth) / availableImageWidth; cropRight = (1f - ImageUtil.getXAlignFactor(image)) * (availableImageWidth - imageWidth) / availableImageWidth; cropTop = ImageUtil.getYAlignFactor(image) * (availableImageHeight - imageHeight) / availableImageHeight; cropBottom = (1f - ImageUtil.getYAlignFactor(image)) * (availableImageHeight - imageHeight) / availableImageHeight; angle = 180; break; case NONE: default: renderWidth = availableImageWidth; renderHeight = availableImageHeight; ratioX = availableImageWidth / normalWidth; ratioY = availableImageHeight / normalHeight; ratioX = ratioX < ratioY ? ratioX : ratioY; ratioY = ratioX; imageWidth = (int)(normalWidth * ratioX); imageHeight = (int)(normalHeight * ratioY); cropLeft = ImageUtil.getXAlignFactor(image) * (availableImageWidth - imageWidth) / availableImageWidth; cropRight = (1f - ImageUtil.getXAlignFactor(image)) * (availableImageWidth - imageWidth) / availableImageWidth; cropTop = ImageUtil.getYAlignFactor(image) * (availableImageHeight - imageHeight) / availableImageHeight; cropBottom = (1f - ImageUtil.getYAlignFactor(image)) * (availableImageHeight - imageHeight) / availableImageHeight; angle = 0; break; } Insets exifCrop = ImageUtil.getExifCrop(image, imageProcessorResult.exifOrientation, cropTop, cropLeft, cropBottom, cropRight); cropLeft = exifCrop.left; cropRight = exifCrop.right; cropTop = exifCrop.top; cropBottom = exifCrop.bottom; } } // insertPageAnchor(); // if (image.getAnchorName() != null) // { // tempBodyWriter.write(""); // } // boolean startedHyperlink = startHyperlink(image,false); slideRelsHelper.exportImage(imageProcessorResult.imagePath); slideHelper.write("\n"); slideHelper.write(" \n"); slideHelper.write(" \n"); String href = getHyperlinkURL(image); if (href != null) { slideHelper.exportHyperlink(href); } slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write("\n"); slideHelper.write(""); slideHelper.write(""); slideHelper.write("\n"); slideHelper.write("\n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); if (image.getModeValue() == ModeEnum.OPAQUE && image.getBackcolor() != null) { slideHelper.write("\n"); } if (!hasPadding) { exportPen(image.getLineBox()); } slideHelper.write(" \n"); slideHelper.write(" \n"); // if(startedHyperlink) // { // endHyperlink(false); // } } } // docHelper.write(""); } private class InternalImageProcessor { private final JRPrintElement imageElement; private final RenderersCache imageRenderersCache; private final boolean needDimension; private final int availableImageWidth; private final int availableImageHeight; protected InternalImageProcessor( JRPrintImage imageElement, int availableImageWidth, int availableImageHeight ) { this.imageElement = imageElement; this.imageRenderersCache = imageElement.isUsingCache() ? renderersCache : new RenderersCache(getJasperReportsContext()); this.needDimension = imageElement.getScaleImageValue() != ScaleImageEnum.FILL_FRAME; // at this point, we do not yet have the exifOrientation, but we do not need it because the available width and height // are used only for non data renderers, which need to produce their data for the image and have nothing to do with exif metadata anyway if ( imageElement.getRotation() == RotationEnum.LEFT || imageElement.getRotation() == RotationEnum.RIGHT ) { this.availableImageWidth = availableImageHeight; this.availableImageHeight = availableImageWidth; } else { this.availableImageWidth = availableImageWidth; this.availableImageHeight = availableImageHeight; } } private InternalImageProcessorResult process(Renderable renderer) throws JRException { 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 Dimension2D dimension = null; if (needDimension) { DimensionRenderable dimensionRenderer = imageRenderersCache.getDimensionRenderable(renderer); dimension = dimensionRenderer == null ? null : dimensionRenderer.getDimension(jasperReportsContext); } ExifOrientationEnum exifOrientation = ExifOrientationEnum.NORMAL; String imagePath = null; // if (image.isLazy()) //FIXMEPPTX learn how to link images // { // // } // else // { if ( renderer instanceof DataRenderable //we do not cache imagePath for non-data renderers because they render width different width/height each time && rendererToImagePathMap.containsKey(renderer.getId()) ) { Pair imagePair = rendererToImagePathMap.get(renderer.getId()); imagePath = imagePair.first(); exifOrientation = imagePair.second(); } else { JRPrintElementIndex imageIndex = getElementIndex(); DataRenderable imageRenderer = getRendererUtil().getImageDataRenderable( imageRenderersCache, renderer, new Dimension(availableImageWidth, availableImageHeight), ModeEnum.OPAQUE == imageElement.getModeValue() ? imageElement.getBackcolor() : null ); byte[] imageData = imageRenderer.getData(jasperReportsContext); exifOrientation = ImageUtil.getExifOrientation(imageData); String fileExtension = JRTypeSniffer.getImageTypeValue(imageData).getFileExtension(); String imageName = IMAGE_NAME_PREFIX + imageIndex.toString() + (fileExtension == null ? "" : ("." + fileExtension)); pptxZip.addEntry(//FIXMEPPTX optimize with a different implementation of entry new FileBufferedZipEntry( "ppt/media/" + imageName, imageData ) ); //presentationRelsHelper.exportImage(imageName, extension); imagePath = imageName; //imagePath = "Pictures/" + imageName; if (imageRenderer == renderer) { //cache imagePath only for true ImageRenderable instances because the wrapping ones render with different width/height each time rendererToImagePathMap.put(renderer.getId(), new Pair<>(imagePath, exifOrientation)); } } // } return new InternalImageProcessorResult(imagePath, dimension, exifOrientation); } } private class InternalImageProcessorResult { protected final String imagePath; protected final Dimension2D dimension; protected final ExifOrientationEnum exifOrientation; protected InternalImageProcessorResult(String imagePath, Dimension2D dimension, ExifOrientationEnum exifOrientation) { this.imagePath = imagePath; this.dimension = dimension; this.exifOrientation = exifOrientation; } } protected JRPrintElementIndex getElementIndex() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < frameIndexStack.size(); i++) { Integer frameIndex = frameIndexStack.get(i); sb.append(frameIndex).append("_"); } JRPrintElementIndex imageIndex = new JRPrintElementIndex( reportIndex, pageIndex, sb.append(elementIndex).toString() ); return imageIndex; } /* * * protected void writeImageMap(String imageMapName, JRPrintHyperlink mainHyperlink, List imageMapAreas) { writer.write("\n"); for (Iterator it = imageMapAreas.iterator(); it.hasNext();) { JRPrintImageAreaHyperlink areaHyperlink = (JRPrintImageAreaHyperlink) it.next(); JRPrintImageArea area = areaHyperlink.getArea(); writer.write(" \n"); } if (mainHyperlink.getHyperlinkTypeValue() != NONE) { writer.write(" \n"); } writer.write("\n"); } protected void writeImageAreaCoordinates(JRPrintImageArea area) { int[] coords = area.getCoordinates(); if (coords != null && coords.length > 0) { StringBuilder coordsEnum = new StringBuilder(coords.length * 4); coordsEnum.append(coords[0]); for (int i = 1; i < coords.length; i++) { coordsEnum.append(','); coordsEnum.append(coords[i]); } writer.write(" coords=\"" + coordsEnum + "\""); } } protected void writeImageAreaHyperlink(JRPrintHyperlink hyperlink) { String href = getHyperlinkURL(hyperlink); if (href == null) { writer.write(" nohref=\"nohref\""); } else { writer.write(" href=\"" + href + "\""); String target = getHyperlinkTarget(hyperlink); if (target != null) { writer.write(" target=\""); writer.write(target); writer.write("\""); } } if (hyperlink.getHyperlinkTooltip() != null) { writer.write(" title=\""); writer.write(JRStringUtil.xmlEncode(hyperlink.getHyperlinkTooltip())); writer.write("\""); } } */ /** * */ public static JRPrintElementIndex getPrintElementIndex(String imageName) { if (!imageName.startsWith(IMAGE_NAME_PREFIX)) { throw new JRRuntimeException( EXCEPTION_MESSAGE_KEY_INVALID_IMAGE_NAME, new Object[]{imageName}); } return JRPrintElementIndex.parsePrintElementIndex(imageName.substring(IMAGE_NAME_PREFIX_LEGTH)); } /** * */ public void exportFrame(JRPrintFrame frame) throws JRException { slideHelper.write("\n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); if (frame.getModeValue() == ModeEnum.OPAQUE && frame.getBackcolor() != null) { slideHelper.write("\n"); } exportPen(frame.getLineBox()); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write("\n"); slideHelper.write(" \n"); slideHelper.write(" \n"); slideHelper.write("\n"); setFrameElementsOffset(frame, false); frameIndexStack.add(elementIndex); List elements = frame.getElements(); if (elements != null && elements.size() > 0) { for (int i = 0; i < elements.size(); i++) { JRPrintElement element = elements.get(i); elementIndex = i; if (filter == null || filter.isToExport(element)) { exportElement(element); } } } frameIndexStack.remove(frameIndexStack.size() - 1); restoreElementOffsets(); } /** * */ protected void exportGenericElement(JRGenericPrintElement element) { GenericElementPptxHandler handler = (GenericElementPptxHandler) GenericElementHandlerEnviroment.getInstance(getJasperReportsContext()).getElementHandler( element.getGenericType(), PPTX_EXPORTER_KEY); if (handler != null) { handler.exportElement(exporterContext, element); } else { if (log.isDebugEnabled()) { log.debug("No PPTX generic element handler for " + element.getGenericType()); } } } // protected boolean startHyperlink(JRPrintHyperlink link, boolean isText) // { // String href = getHyperlinkURL(link); // //// if (href != null) //// { //// String id = (String)hyperlinksMap.get(href); //// if (id == null) //// { //// id = "link" + hyperlinksMap.size(); //// hyperlinksMap.put(href, id); //// } //// //// docHelper.write("\n"); // //// docHelper.write("\n"); //// docHelper.write(" HYPERLINK \"" + JRStringUtil.xmlEncode(href) + "\""); //// //// String target = getHyperlinkTarget(link);//FIXMETARGET //// if (target != null) //// { //// docHelper.write(" \\t \"" + target + "\""); //// } //// //// String tooltip = link.getHyperlinkTooltip(); //// if (tooltip != null) //// { //// docHelper.write(" \\o \"" + JRStringUtil.xmlEncode(tooltip) + "\""); //// } //// //// docHelper.write(" \n"); //// docHelper.write("\n"); //// } // // return href != null; // } protected String getHyperlinkTarget(JRPrintHyperlink link) { String target = null; switch(link.getHyperlinkTargetValue()) { case SELF : { target = "_self"; break; } case BLANK : default : { target = "_blank"; break; } } return target; } protected String getHyperlinkURL(JRPrintHyperlink link) { String href = null; Boolean ignoreHyperlink = HyperlinkUtil.getIgnoreHyperlink(PptxReportConfiguration.PROPERTY_IGNORE_HYPERLINK, link); if (ignoreHyperlink == null) { ignoreHyperlink = getCurrentItemConfiguration().isIgnoreHyperlink(); } if (!ignoreHyperlink) { JRHyperlinkProducer customHandler = getHyperlinkProducer(link); if (customHandler == null) { switch(link.getHyperlinkTypeValue()) { case REFERENCE : { if (link.getHyperlinkReference() != null) { try { href = link.getHyperlinkReference().replaceAll("\\s", URLEncoder.encode(" ","UTF-8")); } catch (UnsupportedEncodingException e) { href = link.getHyperlinkReference(); } } break; } case LOCAL_ANCHOR : { // if (link.getHyperlinkAnchor() != null) // { // href = "#" + link.getHyperlinkAnchor(); // } break; } case LOCAL_PAGE : { // if (link.getHyperlinkPage() != null) // { // href = "#" + JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + link.getHyperlinkPage().toString(); // } break; } case REMOTE_ANCHOR : { if ( link.getHyperlinkReference() != null && link.getHyperlinkAnchor() != null ) { href = link.getHyperlinkReference() + "#" + link.getHyperlinkAnchor(); } break; } case REMOTE_PAGE : { // if ( // link.getHyperlinkReference() != null && // link.getHyperlinkPage() != null // ) // { // href = link.getHyperlinkReference() + "#" + JR_PAGE_ANCHOR_PREFIX + "0_" + link.getHyperlinkPage().toString(); // } break; } case NONE : default : { break; } } } else { href = customHandler.getHyperlink(link); } } return href; } // protected void endHyperlink(boolean isText) // { //// docHelper.write("\n"); //// docHelper.write("\n"); // } // protected void insertPageAnchor() // { // if(startPage) // { // tempBodyWriter.write("\n"); // startPage = false; // } // } @Override protected JRStyledText getStyledText(JRPrintText textElement, boolean setBackcolor) { return styledTextUtil.getProcessedStyledText(textElement, setBackcolor ? allSelector : noBackcolorSelector, getExporterKey()); } @Override public String getExporterKey() { return PPTX_EXPORTER_KEY; } @Override public String getExporterPropertiesPrefix() { return PPTX_EXPORTER_PROPERTIES_PREFIX; } protected String toOOXMLId(JRPrintElement element) { // using hashCode() for now, though in theory there is a risk of collisions // we could use something based on getSourceElementId() and getPrintElementId() // or even a counter since we do not have any references to Ids int hashCode = element.hashCode(); // OOXML object ids are xsd:unsignedInt in the spec, but in practice PowerPoint // only accepts positive signed ints return Integer.toString(hashCode & 0x7FFFFFFF); } protected JRPen getPptxPen(JRLineBox box) { JRBasePen pen = null; Float lineWidth = box.getPen().getLineWidth(); if(lineWidth == 0) { // PPTX does not support side borders // in case side borders are defined for the report element, ensure that all 4 are declared and all of them come with the same settings if( ((JRBasePen)box.getTopPen()).isIdentical(box.getLeftPen()) && ((JRBasePen)box.getTopPen()).isIdentical(box.getBottomPen()) && ((JRBasePen)box.getTopPen()).isIdentical(box.getRightPen()) && box.getTopPen().getLineWidth() > 0 ) { pen = new JRBasePen(box); pen.setLineWidth(box.getTopPen().getLineWidth()); pen.setLineColor(box.getTopPen().getLineColor()); pen.setLineStyle(box.getTopPen().getLineStyleValue()); } } else { pen = new JRBasePen(box); pen.setLineWidth(lineWidth); pen.setLineColor(box.getPen().getLineColor()); pen.setLineStyle(box.getPen().getLineStyleValue()); } return pen; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy