Save This Page
Home » jasperreports-3.0.0-project » net.sf.jasperreports.engine.export.oasis » [javadoc | source]
    1   /*
    2    * ============================================================================
    3    * GNU Lesser General Public License
    4    * ============================================================================
    5    *
    6    * JasperReports - Free Java report-generating library.
    7    * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
    8    *
    9    * This library is free software; you can redistribute it and/or
   10    * modify it under the terms of the GNU Lesser General Public
   11    * License as published by the Free Software Foundation; either
   12    * version 2.1 of the License, or (at your option) any later version.
   13    *
   14    * This library is distributed in the hope that it will be useful,
   15    * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   17    * Lesser General Public License for more details.
   18    *
   19    * You should have received a copy of the GNU Lesser General Public
   20    * License along with this library; if not, write to the Free Software
   21    * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
   22    *
   23    * JasperSoft Corporation
   24    * 303 Second Street, Suite 450 North
   25    * San Francisco, CA 94107
   26    * http://www.jaspersoft.com
   27    */
   28   
   29   /*
   30    * Special thanks to Google 'Summer of Code 2005' program for supporting this development
   31    *
   32    * Contributors:
   33    * Majid Ali Khan - majidkk@users.sourceforge.net
   34    * Frank Sch?nheit - Frank.Schoenheit@Sun.COM
   35    */
   36   package net.sf.jasperreports.engine.export.oasis;
   37   
   38   import java.awt.Color;
   39   import java.awt.Dimension;
   40   import java.awt.geom.Dimension2D;
   41   import java.io.File;
   42   import java.io.FileOutputStream;
   43   import java.io.IOException;
   44   import java.io.OutputStream;
   45   import java.io.Writer;
   46   import java.text.AttributedCharacterIterator;
   47   import java.util.ArrayList;
   48   import java.util.HashMap;
   49   import java.util.Iterator;
   50   import java.util.LinkedList;
   51   import java.util.List;
   52   import java.util.Map;
   53   
   54   import net.sf.jasperreports.engine.JRAbstractExporter;
   55   import net.sf.jasperreports.engine.JRAlignment;
   56   import net.sf.jasperreports.engine.JRElement;
   57   import net.sf.jasperreports.engine.JRException;
   58   import net.sf.jasperreports.engine.JRExporterParameter;
   59   import net.sf.jasperreports.engine.JRHyperlink;
   60   import net.sf.jasperreports.engine.JRImage;
   61   import net.sf.jasperreports.engine.JRImageRenderer;
   62   import net.sf.jasperreports.engine.JRLine;
   63   import net.sf.jasperreports.engine.JRPrintElement;
   64   import net.sf.jasperreports.engine.JRPrintElementIndex;
   65   import net.sf.jasperreports.engine.JRPrintEllipse;
   66   import net.sf.jasperreports.engine.JRPrintFrame;
   67   import net.sf.jasperreports.engine.JRPrintHyperlink;
   68   import net.sf.jasperreports.engine.JRPrintImage;
   69   import net.sf.jasperreports.engine.JRPrintLine;
   70   import net.sf.jasperreports.engine.JRPrintPage;
   71   import net.sf.jasperreports.engine.JRPrintRectangle;
   72   import net.sf.jasperreports.engine.JRPrintText;
   73   import net.sf.jasperreports.engine.JRRenderable;
   74   import net.sf.jasperreports.engine.JRRuntimeException;
   75   import net.sf.jasperreports.engine.JRWrappingSvgRenderer;
   76   import net.sf.jasperreports.engine.JasperPrint;
   77   import net.sf.jasperreports.engine.export.CutsInfo;
   78   import net.sf.jasperreports.engine.export.ExporterNature;
   79   import net.sf.jasperreports.engine.export.JRExportProgressMonitor;
   80   import net.sf.jasperreports.engine.export.JRExporterGridCell;
   81   import net.sf.jasperreports.engine.export.JRGridLayout;
   82   import net.sf.jasperreports.engine.export.JRHyperlinkProducer;
   83   import net.sf.jasperreports.engine.export.JRHyperlinkProducerFactory;
   84   import net.sf.jasperreports.engine.export.JROriginExporterFilter;
   85   import net.sf.jasperreports.engine.export.oasis.zip.FileBufferedOasisZip;
   86   import net.sf.jasperreports.engine.export.oasis.zip.FileBufferedOasisZipEntry;
   87   import net.sf.jasperreports.engine.export.oasis.zip.OasisZip;
   88   import net.sf.jasperreports.engine.export.oasis.zip.OasisZipEntry;
   89   import net.sf.jasperreports.engine.util.JRProperties;
   90   import net.sf.jasperreports.engine.util.JRStringUtil;
   91   import net.sf.jasperreports.engine.util.JRStyledText;
   92   
   93   
   94   /**
   95    * Exports a JasperReports document to ODF format. It has character output type and exports the document to a
   96    * grid-based layout.
   97    * @author Teodor Danciu (teodord@users.sourceforge.net)
   98    * @version $Id: JROdtExporter.java 2127 2008-03-12 13:33:26Z teodord $
   99    */
  100   public class JROdtExporter extends JRAbstractExporter
  101   {
  102   
  103   	private static final String ODT_ORIGIN_EXPORTER_FILTER_PREFIX = JRProperties.PROPERTY_PREFIX + "export.odt.exclude.origin.";
  104   
  105   	/**
  106   	 *
  107   	 */
  108   	protected static final String JR_PAGE_ANCHOR_PREFIX = "JR_PAGE_ANCHOR_";
  109   
  110   	/**
  111   	 *
  112   	 */
  113   	protected static final String HORIZONTAL_ALIGN_LEFT = "start";
  114   	protected static final String HORIZONTAL_ALIGN_RIGHT = "end";
  115   	protected static final String HORIZONTAL_ALIGN_CENTER = "center";
  116   	protected static final String HORIZONTAL_ALIGN_JUSTIFY = "justified";
  117   
  118   	/**
  119   	 *
  120   	 */
  121   	protected static final String VERTICAL_ALIGN_TOP = "top";
  122   	protected static final String VERTICAL_ALIGN_MIDDLE = "middle";
  123   	protected static final String VERTICAL_ALIGN_BOTTOM = "bottom";
  124   
  125   	public static final String IMAGE_NAME_PREFIX = "img_";
  126   	protected static final int IMAGE_NAME_PREFIX_LEGTH = IMAGE_NAME_PREFIX.length();
  127   
  128   	/**
  129   	 *
  130   	 */
  131   	protected Writer tempBodyWriter = null;
  132   	protected Writer tempStyleWriter = null;
  133   
  134   	protected JRExportProgressMonitor progressMonitor = null;
  135   	protected Map rendererToImagePathMap = null;
  136   	protected Map imageMaps;
  137   	protected List imagesToProcess = null;
  138   
  139   	protected int reportIndex = 0;
  140   	protected int pageIndex = 0;
  141   	protected int tableIndex = 0;
  142   	protected boolean startPage;
  143   
  144   	/**
  145   	 *
  146   	 */
  147   	protected String encoding = null;
  148   
  149   
  150   	/**
  151   	 *
  152   	 */
  153   	protected boolean isWrapBreakWord = false;
  154   
  155   	protected Map fontMap = null;
  156   
  157   	private LinkedList backcolorStack;
  158   	private Color backcolor;
  159   
  160   	private StyleCache styleCache = null;
  161   
  162   	protected JRHyperlinkProducerFactory hyperlinkProducerFactory;
  163   	protected ExporterNature nature = null;
  164   
  165   
  166   	public JROdtExporter()
  167   	{
  168   		backcolorStack = new LinkedList();
  169   		backcolor = null;
  170   	}
  171   
  172   
  173   	/**
  174   	 *
  175   	 */
  176   	public void exportReport() throws JRException
  177   	{
  178   		progressMonitor = (JRExportProgressMonitor)parameters.get(JRExporterParameter.PROGRESS_MONITOR);
  179   
  180   		/*   */
  181   		setOffset();
  182   
  183   		try
  184   		{
  185   			/*   */
  186   			setExportContext();
  187   
  188   			/*   */
  189   			setInput();
  190   
  191   			if (!parameters.containsKey(JRExporterParameter.FILTER))
  192   			{
  193   				filter = JROriginExporterFilter.getFilter(jasperPrint.getPropertiesMap(), ODT_ORIGIN_EXPORTER_FILTER_PREFIX);
  194   			}
  195   
  196   			/*   */
  197   			if (!isModeBatch)
  198   			{
  199   				setPageRange();
  200   			}
  201   
  202   			encoding =
  203   				getStringParameterOrDefault(
  204   					JRExporterParameter.CHARACTER_ENCODING,
  205   					JRExporterParameter.PROPERTY_CHARACTER_ENCODING
  206   					);
  207   
  208   			rendererToImagePathMap = new HashMap();
  209   			imageMaps = new HashMap();
  210   			imagesToProcess = new ArrayList();
  211   
  212   			fontMap = (Map) parameters.get(JRExporterParameter.FONT_MAP);
  213   
  214   			setHyperlinkProducerFactory();
  215   
  216   			nature = new JROdtExporterNature(filter);
  217   
  218   			OutputStream os = (OutputStream)parameters.get(JRExporterParameter.OUTPUT_STREAM);
  219   			if (os != null)
  220   			{
  221   				try
  222   				{
  223   					exportReportToOasisZip(os);
  224   				}
  225   				catch (IOException e)
  226   				{
  227   					throw new JRException("Error trying to export to output stream : " + jasperPrint.getName(), e);
  228   				}
  229   			}
  230   			else
  231   			{
  232   				File destFile = (File)parameters.get(JRExporterParameter.OUTPUT_FILE);
  233   				if (destFile == null)
  234   				{
  235   					String fileName = (String)parameters.get(JRExporterParameter.OUTPUT_FILE_NAME);
  236   					if (fileName != null)
  237   					{
  238   						destFile = new File(fileName);
  239   					}
  240   					else
  241   					{
  242   						throw new JRException("No output specified for the exporter.");
  243   					}
  244   				}
  245   
  246   				try
  247   				{
  248   					os = new FileOutputStream(destFile);
  249   					exportReportToOasisZip(os);
  250   				}
  251   				catch (IOException e)
  252   				{
  253   					throw new JRException("Error trying to export to file : " + destFile, e);
  254   				}
  255   				finally
  256   				{
  257   					if (os != null)
  258   					{
  259   						try
  260   						{
  261   							os.close();
  262   						}
  263   						catch(IOException e)
  264   						{
  265   						}
  266   					}
  267   				}
  268   			}
  269   		}
  270   		finally
  271   		{
  272   			resetExportContext();
  273   		}
  274   	}
  275   
  276   
  277   	protected void setHyperlinkProducerFactory()
  278   	{
  279   		hyperlinkProducerFactory = (JRHyperlinkProducerFactory) parameters.get(JRExporterParameter.HYPERLINK_PRODUCER_FACTORY);
  280   	}
  281   
  282   
  283   	/**
  284   	 *
  285   	 */
  286   	public static JRPrintImage getImage(List jasperPrintList, String imageName)
  287   	{
  288   		return getImage(jasperPrintList, getPrintElementIndex(imageName));
  289   	}
  290   
  291   
  292   	public static JRPrintImage getImage(List jasperPrintList, JRPrintElementIndex imageIndex)
  293   	{
  294   		JasperPrint report = (JasperPrint)jasperPrintList.get(imageIndex.getReportIndex());
  295   		JRPrintPage page = (JRPrintPage)report.getPages().get(imageIndex.getPageIndex());
  296   
  297   		Integer[] elementIndexes = imageIndex.getAddressArray();
  298   		Object element = page.getElements().get(elementIndexes[0].intValue());
  299   
  300   		for (int i = 1; i < elementIndexes.length; ++i)
  301   		{
  302   			JRPrintFrame frame = (JRPrintFrame) element;
  303   			element = frame.getElements().get(elementIndexes[i].intValue());
  304   		}
  305   
  306   		return (JRPrintImage) element;
  307   	}
  308   
  309   
  310   	/**
  311   	 *
  312   	 */
  313   	protected void exportReportToOasisZip(OutputStream os) throws JRException, IOException
  314   	{
  315   		OasisZip oasisZip = new FileBufferedOasisZip();
  316   
  317   		OasisZipEntry tempBodyEntry = new FileBufferedOasisZipEntry(null);
  318   		OasisZipEntry tempStyleEntry = new FileBufferedOasisZipEntry(null);
  319   
  320   		tempBodyWriter = tempBodyEntry.getWriter();
  321   		tempStyleWriter = tempStyleEntry.getWriter();
  322   
  323   		styleCache = new StyleCache(tempStyleWriter, fontMap);
  324   
  325   		Writer stylesWriter = oasisZip.getStylesEntry().getWriter();
  326   
  327   		StyleBuilder styleBuilder = new StyleBuilder(jasperPrintList, stylesWriter);
  328   		styleBuilder.build();
  329   
  330   		stylesWriter.close();
  331   
  332   		for(reportIndex = 0; reportIndex < jasperPrintList.size(); reportIndex++)
  333   		{
  334   			jasperPrint = (JasperPrint)jasperPrintList.get(reportIndex);
  335   
  336   			List pages = jasperPrint.getPages();
  337   			if (pages != null && pages.size() > 0)
  338   			{
  339   				if (isModeBatch)
  340   				{
  341   					startPageIndex = 0;
  342   					endPageIndex = pages.size() - 1;
  343   				}
  344   
  345   				JRPrintPage page = null;
  346   				for(pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++)
  347   				{
  348   					if (Thread.currentThread().isInterrupted())
  349   					{
  350   						throw new JRException("Current thread interrupted.");
  351   					}
  352   
  353   					page = (JRPrintPage)pages.get(pageIndex);
  354   
  355   					exportPage(page);
  356   				}
  357   			}
  358   		}
  359   
  360   
  361   		tempBodyWriter.flush();
  362   		tempStyleWriter.flush();
  363   
  364   
  365   		tempBodyWriter.close();
  366   		tempStyleWriter.close();
  367   
  368   
  369   		/*   */
  370   		ContentBuilder contentBuilder =
  371   			new ContentBuilder(
  372   				oasisZip.getContentEntry(),
  373   				tempStyleEntry,
  374   				tempBodyEntry,
  375   				styleCache.getFontFaces()
  376   				);
  377   		contentBuilder.build();
  378   
  379   		tempStyleEntry.dispose();
  380   		tempBodyEntry.dispose();
  381   
  382   		if ((imagesToProcess != null && imagesToProcess.size() > 0))
  383   		{
  384   			for(Iterator it = imagesToProcess.iterator(); it.hasNext();)
  385   			{
  386   				JRPrintElementIndex imageIndex = (JRPrintElementIndex)it.next();
  387   
  388   				JRPrintImage image = getImage(jasperPrintList, imageIndex);
  389   				JRRenderable renderer = image.getRenderer();
  390   				if (renderer.getType() == JRRenderable.TYPE_SVG)
  391   				{
  392   					renderer =
  393   						new JRWrappingSvgRenderer(
  394   							renderer,
  395   							new Dimension(image.getWidth(), image.getHeight()),
  396   							JRElement.MODE_OPAQUE == image.getMode() ? image.getBackcolor() : null
  397   							);
  398   				}
  399   
  400   				oasisZip.addEntry(//FIXMEODT optimize with a different implementation of entry
  401   					new FileBufferedOasisZipEntry(
  402   						"Pictures/" + getImageName(imageIndex),
  403   						renderer.getImageData()
  404   						)
  405   					);
  406   			}
  407   		}
  408   
  409   		oasisZip.zipEntries(os);
  410   
  411   		oasisZip.dispose();
  412   	}
  413   
  414   
  415   	/**
  416   	 *
  417   	 */
  418   	protected void exportPage(JRPrintPage page) throws JRException, IOException
  419   	{
  420   		startPage = true;
  421   		JRGridLayout layout =
  422   			new JRGridLayout(
  423   				nature,
  424   				page.getElements(),
  425   				jasperPrint.getPageWidth(),
  426   				jasperPrint.getPageHeight(),
  427   				globalOffsetX,
  428   				globalOffsetY,
  429   				null //address
  430   				);
  431   
  432   		exportGrid(layout, null);
  433   
  434   		if (progressMonitor != null)
  435   		{
  436   			progressMonitor.afterPageExport();
  437   		}
  438   	}
  439   
  440   
  441   	/**
  442   	 *
  443   	 */
  444   	protected void exportGrid(JRGridLayout gridLayout, JRPrintElementIndex frameIndex) throws IOException, JRException
  445   	{
  446   		CutsInfo xCuts = gridLayout.getXCuts();
  447   		JRExporterGridCell[][] grid = gridLayout.getGrid();
  448   
  449   		TableBuilder tableBuilder = frameIndex == null
  450   			? new TableBuilder(reportIndex, pageIndex, tempBodyWriter, tempStyleWriter)
  451   			: new TableBuilder(frameIndex.toString(), tempBodyWriter, tempStyleWriter);
  452   
  453   		tableBuilder.buildTableStyle();
  454   		tableBuilder.buildTableHeader();
  455   
  456   		for(int col = 1; col < xCuts.size(); col++)
  457   		{
  458   			tableBuilder.buildColumnStyle(
  459   					col - 1,
  460   					xCuts.getCut(col) - xCuts.getCut(col - 1)
  461   					);
  462   			tableBuilder.buildColumnHeader(col - 1);
  463   			tableBuilder.buildColumnFooter();
  464   		}
  465   
  466   		JRPrintElement element = null;
  467   		for(int row = 0; row < grid.length; row++)
  468   		{
  469   			//JRExporterGridCell[] gridRow = grid[row];
  470   
  471   			int emptyCellColSpan = 0;
  472   			int emptyCellWidth = 0;
  473   			int rowHeight = gridLayout.getRowHeight(row);
  474   
  475   			tableBuilder.buildRowStyle(row, rowHeight);
  476   			tableBuilder.buildRowHeader(row);
  477   
  478   			for(int col = 0; col < grid[0].length; col++)
  479   			{
  480   				JRExporterGridCell gridCell = grid[row][col];
  481   				if (gridCell == JRExporterGridCell.OCCUPIED_CELL)
  482   				{
  483   					if (emptyCellColSpan > 0)
  484   					{
  485   						writeEmptyCell(gridCell, emptyCellColSpan, emptyCellWidth, rowHeight);
  486   						emptyCellColSpan = 0;
  487   						emptyCellWidth = 0;
  488   					}
  489   
  490   					writeOccupiedCells(1);
  491   				}
  492   				else if(gridCell.getWrapper() != null)
  493   				{
  494   					if (emptyCellColSpan > 0)
  495   					{
  496   						writeEmptyCell(gridCell, emptyCellColSpan, emptyCellWidth, rowHeight);
  497   						emptyCellColSpan = 0;
  498   						emptyCellWidth = 0;
  499   					}
  500   
  501   					element = gridCell.getWrapper().getElement();
  502   
  503   					if (element instanceof JRPrintLine)
  504   					{
  505   						exportLine(tableBuilder, (JRPrintLine)element, gridCell);
  506   					}
  507   					else if (element instanceof JRPrintRectangle)
  508   					{
  509   						exportRectangle(tableBuilder, (JRPrintRectangle)element, gridCell);
  510   					}
  511   					else if (element instanceof JRPrintEllipse)
  512   					{
  513   						exportEllipse(tableBuilder, (JRPrintEllipse)element, gridCell);
  514   					}
  515   					else if (element instanceof JRPrintImage)
  516   					{
  517   						exportImage(tableBuilder, (JRPrintImage)element, gridCell);
  518   					}
  519   					else if (element instanceof JRPrintText)
  520   					{
  521   						exportText(tableBuilder, (JRPrintText)element, gridCell);
  522   					}
  523   					else if (element instanceof JRPrintFrame)
  524   					{
  525   						exportFrame(tableBuilder, (JRPrintFrame)element, gridCell);
  526   					}
  527   
  528   					//x += gridCell.colSpan - 1;
  529   				}
  530   				else
  531   				{
  532   					emptyCellColSpan++;
  533   					emptyCellWidth += gridCell.getWidth();
  534   				}
  535   			}
  536   
  537   			if (emptyCellColSpan > 0)
  538   			{
  539   				writeEmptyCell(null, emptyCellColSpan, emptyCellWidth, rowHeight);
  540   			}
  541   
  542   			tableBuilder.buildRowFooter();
  543   		}
  544   
  545   		tableBuilder.buildTableFooter();
  546   	}
  547   
  548   
  549   	private void writeEmptyCell(JRExporterGridCell gridCell, int emptyCellColSpan, int emptyCellWidth, int rowHeight) throws IOException
  550   	{
  551   		tempBodyWriter.write("<table:table-cell");
  552   		//tempBodyWriter.write(" office:value-type=\"string\"");
  553   		tempBodyWriter.write(" table:style-name=\"empty-cell\"");
  554   		if (emptyCellColSpan > 1)
  555   		{
  556   			tempBodyWriter.write(" table:number-columns-spanned=\"" + emptyCellColSpan + "\"");
  557   		}
  558   		tempBodyWriter.write("/>\n");
  559   
  560   		writeOccupiedCells(emptyCellColSpan - 1);
  561   	}
  562   
  563   
  564   	private void writeOccupiedCells(int count) throws IOException
  565   	{
  566   		for(int i = 0; i < count; i++)
  567   		{
  568   			tempBodyWriter.write("<table:covered-table-cell/>\n");
  569   		}
  570   	}
  571   
  572   
  573   	/**
  574   	 *
  575   	 */
  576   	protected void exportLine(TableBuilder tableBuilder, JRPrintLine line, JRExporterGridCell gridCell) throws IOException
  577   	{
  578   		tableBuilder.buildCellHeader(null, gridCell.getColSpan(), gridCell.getRowSpan());
  579   
  580   		double x1, y1, x2, y2;
  581   
  582   		if (line.getDirection() == JRLine.DIRECTION_TOP_DOWN)
  583   		{
  584   			x1 = Utility.translatePixelsToInches(0);
  585   			y1 = Utility.translatePixelsToInches(0);
  586   			x2 = Utility.translatePixelsToInches(line.getWidth() - 1);
  587   			y2 = Utility.translatePixelsToInches(line.getHeight() - 1);
  588   		}
  589   		else
  590   		{
  591   			x1 = Utility.translatePixelsToInches(0);
  592   			y1 = Utility.translatePixelsToInches(line.getHeight() - 1);
  593   			x2 = Utility.translatePixelsToInches(line.getWidth() - 1);
  594   			y2 = Utility.translatePixelsToInches(0);
  595   		}
  596   
  597   		tempBodyWriter.write("<text:p>");
  598   		insertPageAnchor();
  599   		tempBodyWriter.write(
  600   				"<draw:line text:anchor-type=\"paragraph\" "
  601   				+ "draw:style-name=\"" + styleCache.getGraphicStyle(line) + "\" "
  602   				+ "svg:x1=\"" + x1 + "in\" "
  603   				+ "svg:y1=\"" + y1 + "in\" "
  604   				+ "svg:x2=\"" + x2 + "in\" "
  605   				+ "svg:y2=\"" + y2 + "in\">"
  606   				//+ "</draw:line>"
  607   				+ "<text:p/></draw:line>"
  608   				+ "</text:p>"
  609   				);
  610   		tableBuilder.buildCellFooter();
  611   	}
  612   
  613   
  614   	/**
  615   	 *
  616   	 */
  617   	protected void exportRectangle(TableBuilder tableBuilder, JRPrintRectangle rectangle, JRExporterGridCell gridCell) throws IOException
  618   	{
  619   		tableBuilder.buildCellHeader(styleCache.getCellStyle(rectangle), gridCell.getColSpan(), gridCell.getRowSpan());
  620   		tableBuilder.buildCellFooter();
  621   	}
  622   
  623   
  624   	/**
  625   	 *
  626   	 */
  627   	protected void exportEllipse(TableBuilder tableBuilder, JRPrintEllipse ellipse, JRExporterGridCell gridCell) throws IOException
  628   	{
  629   		tableBuilder.buildCellHeader(null, gridCell.getColSpan(), gridCell.getRowSpan());
  630   		tempBodyWriter.write("<text:p>");
  631   		insertPageAnchor();
  632   		tempBodyWriter.write(
  633   			"<draw:ellipse text:anchor-type=\"paragraph\" "
  634   			+ "draw:style-name=\"" + styleCache.getGraphicStyle(ellipse) + "\" "
  635   			+ "svg:width=\"" + Utility.translatePixelsToInches(ellipse.getWidth()) + "in\" "
  636   			+ "svg:height=\"" + Utility.translatePixelsToInches(ellipse.getHeight()) + "in\" "
  637   			+ "svg:x=\"0in\" "
  638   			+ "svg:y=\"0in\">"
  639   			+ "<text:p/></draw:ellipse></text:p>"
  640   			);
  641   		tableBuilder.buildCellFooter();
  642   	}
  643   
  644   
  645   	/**
  646   	 *
  647   	 */
  648   	protected void exportText(TableBuilder tableBuilder, JRPrintText text, JRExporterGridCell gridCell) throws IOException
  649   	{
  650   		tableBuilder.buildCellHeader(styleCache.getCellStyle(text), gridCell.getColSpan(), gridCell.getRowSpan());
  651   
  652   		JRStyledText styledText = getStyledText(text);
  653   
  654   		int textLength = 0;
  655   
  656   		if (styledText != null)
  657   		{
  658   			textLength = styledText.length();
  659   		}
  660   
  661   //		if (isWrapBreakWord)
  662   //		{
  663   //			styleBuffer.append("width: " + gridCell.width + "; ");
  664   //			styleBuffer.append("word-wrap: break-word; ");
  665   //		}
  666   
  667   //		if (text.getLineSpacing() != JRTextElement.LINE_SPACING_SINGLE)
  668   //		{
  669   //			styleBuffer.append("line-height: " + text.getLineSpacingFactor() + "; ");
  670   //		}
  671   
  672   //		if (styleBuffer.length() > 0)
  673   //		{
  674   //			writer.write(" style=\"");
  675   //			writer.write(styleBuffer.toString());
  676   //			writer.write("\"");
  677   //		}
  678   //
  679   //		writer.write(">");
  680   		tempBodyWriter.write("<text:p text:style-name=\"");
  681   		tempBodyWriter.write(styleCache.getParagraphStyle(text));
  682   		tempBodyWriter.write("\">");
  683   		insertPageAnchor();
  684   		if (text.getAnchorName() != null)
  685   		{
  686   			tempBodyWriter.write("<text:bookmark text:name=\"");
  687   			tempBodyWriter.write(text.getAnchorName());
  688   			tempBodyWriter.write("\"/>");
  689   		}
  690   
  691   		boolean startedHyperlink = startHyperlink(text, true);
  692   
  693   		if (textLength > 0)
  694   		{
  695   			exportStyledText(styledText);
  696   		}
  697   
  698   		if (startedHyperlink)
  699   		{
  700   			endHyperlink(true);
  701   		}
  702   
  703   		tempBodyWriter.write("</text:p>\n");
  704   
  705   		tableBuilder.buildCellFooter();
  706   	}
  707   
  708   
  709   	/**
  710   	 *
  711   	 */
  712   	protected void exportStyledText(JRStyledText styledText) throws IOException
  713   	{
  714   		String text = styledText.getText();
  715   
  716   		int runLimit = 0;
  717   
  718   		AttributedCharacterIterator iterator = styledText.getAttributedString().getIterator();
  719   
  720   		while(runLimit < styledText.length() && (runLimit = iterator.getRunLimit()) <= styledText.length())
  721   		{
  722   			exportStyledTextRun(iterator.getAttributes(), text.substring(iterator.getIndex(), runLimit));
  723   
  724   			iterator.setIndex(runLimit);
  725   		}
  726   	}
  727   
  728   
  729   	/**
  730   	 *
  731   	 */
  732   	protected void exportStyledTextRun(Map attributes, String text) throws IOException
  733   	{
  734   		String textSpanStyleName = styleCache.getTextSpanStyle(attributes, text);
  735   
  736   		tempBodyWriter.write("<text:span");
  737   		tempBodyWriter.write(" text:style-name=\"" + textSpanStyleName + "\"");
  738   		tempBodyWriter.write(">");
  739   
  740   		if (text != null)
  741   		{
  742   			tempBodyWriter.write(Utility.replaceNewLineWithLineBreak(JRStringUtil.xmlEncode(text)));//FIXMEODT try something nicer for replace
  743   		}
  744   
  745   		tempBodyWriter.write("</text:span>");
  746   	}
  747   
  748   	/**
  749   	 *
  750   	 */
  751   	protected void exportImage(TableBuilder tableBuilder, JRPrintImage image, JRExporterGridCell gridCell) throws JRException, IOException
  752   	{
  753   		int topPadding = 
  754   			Math.max(image.getLineBox().getTopPadding().intValue(), Math.round(image.getLineBox().getTopPen().getLineWidth().floatValue()));
  755   		int leftPadding = 
  756   			Math.max(image.getLineBox().getLeftPadding().intValue(), Math.round(image.getLineBox().getLeftPen().getLineWidth().floatValue()));
  757   		int bottomPadding = 
  758   			Math.max(image.getLineBox().getBottomPadding().intValue(), Math.round(image.getLineBox().getBottomPen().getLineWidth().floatValue()));
  759   		int rightPadding = 
  760   			Math.max(image.getLineBox().getRightPadding().intValue(), Math.round(image.getLineBox().getRightPen().getLineWidth().floatValue()));
  761   
  762   		int availableImageWidth = image.getWidth() - leftPadding - rightPadding;
  763   		availableImageWidth = availableImageWidth < 0 ? 0 : availableImageWidth;
  764   
  765   		int availableImageHeight = image.getHeight() - topPadding - bottomPadding;
  766   		availableImageHeight = availableImageHeight < 0 ? 0 : availableImageHeight;
  767   
  768   		int width = availableImageWidth;
  769   		int height = availableImageHeight;
  770   
  771   		int xoffset = 0;
  772   		int yoffset = 0;
  773   
  774   		tableBuilder.buildCellHeader(styleCache.getCellStyle(image), gridCell.getColSpan(), gridCell.getRowSpan());
  775   
  776   		JRRenderable renderer = image.getRenderer();
  777   
  778   		if (
  779   			renderer != null &&
  780   			availableImageWidth > 0 &&
  781   			availableImageHeight > 0
  782   			)
  783   		{
  784   			if (renderer.getType() == JRRenderable.TYPE_IMAGE && !image.isLazy())
  785   			{
  786   				// Non-lazy image renderers are all asked for their image data at some point.
  787   				// Better to test and replace the renderer now, in case of lazy load error.
  788   				renderer = JRImageRenderer.getOnErrorRendererForImageData(renderer, image.getOnErrorType());
  789   			}
  790   		}
  791   		else
  792   		{
  793   			renderer = null;
  794   		}
  795   
  796   		if (renderer != null)
  797   		{
  798   			float xalignFactor = getXAlignFactor(image);
  799   			float yalignFactor = getYAlignFactor(image);
  800   
  801   			switch (image.getScaleImage())
  802   			{
  803   				case JRImage.SCALE_IMAGE_FILL_FRAME :
  804   				{
  805   					width = availableImageWidth;
  806   					height = availableImageHeight;
  807   					xoffset = 0;
  808   					yoffset = 0;
  809   					break;
  810   				}
  811   				case JRImage.SCALE_IMAGE_CLIP :
  812   				case JRImage.SCALE_IMAGE_RETAIN_SHAPE :
  813   				default :
  814   				{
  815   					double normalWidth = availableImageWidth;
  816   					double normalHeight = availableImageHeight;
  817   
  818   					if (!image.isLazy())
  819   					{
  820   						// Image load might fail.
  821   						JRRenderable tmpRenderer =
  822   							JRImageRenderer.getOnErrorRendererForDimension(renderer, image.getOnErrorType());
  823   						Dimension2D dimension = tmpRenderer == null ? null : tmpRenderer.getDimension();
  824   						// If renderer was replaced, ignore image dimension.
  825   						if (tmpRenderer == renderer && dimension != null)
  826   						{
  827   							normalWidth = dimension.getWidth();
  828   							normalHeight = dimension.getHeight();
  829   						}
  830   					}
  831   
  832   					if (availableImageHeight > 0)
  833   					{
  834   						double ratio = (double)normalWidth / (double)normalHeight;
  835   
  836   						if( ratio > availableImageWidth / (double)availableImageHeight )
  837   						{
  838   							width = availableImageWidth;
  839   							height = (int)(width/ratio);
  840   
  841   						}
  842   						else
  843   						{
  844   							height = availableImageHeight;
  845   							width = (int)(ratio * height);
  846   						}
  847   					}
  848   
  849   					xoffset = (int)(xalignFactor * (availableImageWidth - width));
  850   					yoffset = (int)(yalignFactor * (availableImageHeight - height));
  851   				}
  852   			}
  853   
  854   			tempBodyWriter.write("<text:p>");
  855   			insertPageAnchor();
  856   			if (image.getAnchorName() != null)
  857   			{
  858   				tempBodyWriter.write("<text:bookmark text:name=\"");
  859   				tempBodyWriter.write(image.getAnchorName());
  860   				tempBodyWriter.write("\"/>");
  861   			}
  862   
  863   
  864   			boolean startedHyperlink = startHyperlink(image,false);
  865   
  866   			tempBodyWriter.write("<draw:frame text:anchor-type=\"paragraph\" "
  867   					+ "draw:style-name=\"" + styleCache.getGraphicStyle(image) + "\" "
  868   					+ "svg:x=\"" + Utility.translatePixelsToInches(leftPadding + xoffset) + "in\" "
  869   					+ "svg:y=\"" + Utility.translatePixelsToInches(topPadding + yoffset) + "in\" "
  870   					+ "svg:width=\"" + Utility.translatePixelsToInches(width) + "in\" "
  871   					+ "svg:height=\"" + Utility.translatePixelsToInches(height) + "in\">"
  872   					);
  873   			tempBodyWriter.write("<draw:image ");
  874   			tempBodyWriter.write(" xlink:href=\"" + getImagePath(renderer, image.isLazy(), gridCell) + "\"");
  875   			tempBodyWriter.write(" xlink:type=\"simple\"");
  876   			tempBodyWriter.write(" xlink:show=\"embed\"");
  877   			tempBodyWriter.write(" xlink:actuate=\"onLoad\"");
  878   			tempBodyWriter.write("/>\n");
  879   
  880   			tempBodyWriter.write("</draw:frame>");
  881   			if(startedHyperlink)
  882   			{
  883   				endHyperlink(false);
  884   			}
  885   			tempBodyWriter.write("</text:p>");
  886   		}
  887   
  888   		tableBuilder.buildCellFooter();
  889   	}
  890   
  891   
  892   	/**
  893   	 *
  894   	 */
  895   	protected String getImagePath(JRRenderable renderer, boolean isLazy, JRExporterGridCell gridCell) throws IOException
  896   	{
  897   		String imagePath = null;
  898   
  899   		if (renderer != null)
  900   		{
  901   			if (renderer.getType() == JRRenderable.TYPE_IMAGE && rendererToImagePathMap.containsKey(renderer.getId()))
  902   			{
  903   				imagePath = (String)rendererToImagePathMap.get(renderer.getId());
  904   			}
  905   			else
  906   			{
  907   				if (isLazy)
  908   				{
  909   					imagePath = ((JRImageRenderer)renderer).getImageLocation();
  910   				}
  911   				else
  912   				{
  913   					JRPrintElementIndex imageIndex = getElementIndex(gridCell);
  914   					imagesToProcess.add(imageIndex);
  915   
  916   					String imageName = getImageName(imageIndex);
  917   					imagePath = "Pictures/" + imageName;
  918   				}
  919   
  920   				rendererToImagePathMap.put(renderer.getId(), imagePath);
  921   			}
  922   		}
  923   
  924   		return imagePath;
  925   	}
  926   
  927   
  928   	protected JRPrintElementIndex getElementIndex(JRExporterGridCell gridCell)
  929   	{
  930   		JRPrintElementIndex imageIndex =
  931   			new JRPrintElementIndex(
  932   					reportIndex,
  933   					pageIndex,
  934   					gridCell.getWrapper().getAddress()
  935   					);
  936   		return imageIndex;
  937   	}
  938   
  939   
  940   	/**
  941   	 *
  942   	 *
  943   	protected void writeImageMap(String imageMapName, JRPrintHyperlink mainHyperlink, List imageMapAreas) throws IOException
  944   	{
  945   		writer.write("<map name=\"" + imageMapName + "\">\n");
  946   
  947   		for (Iterator it = imageMapAreas.iterator(); it.hasNext();)
  948   		{
  949   			JRPrintImageAreaHyperlink areaHyperlink = (JRPrintImageAreaHyperlink) it.next();
  950   			JRPrintImageArea area = areaHyperlink.getArea();
  951   
  952   			writer.write("  <area shape=\"" + JRPrintImageArea.getHtmlShape(area.getShape()) + "\"");
  953   			writeImageAreaCoordinates(area);
  954   			writeImageAreaHyperlink(areaHyperlink.getHyperlink());
  955   			writer.write("/>\n");
  956   		}
  957   
  958   		if (mainHyperlink.getHyperlinkType() != JRHyperlink.HYPERLINK_TYPE_NONE)
  959   		{
  960   			writer.write("  <area shape=\"default\"");
  961   			writeImageAreaHyperlink(mainHyperlink);
  962   			writer.write("/>\n");
  963   		}
  964   
  965   		writer.write("</map>\n");
  966   	}
  967   
  968   
  969   	protected void writeImageAreaCoordinates(JRPrintImageArea area) throws IOException
  970   	{
  971   		int[] coords = area.getCoordinates();
  972   		if (coords != null && coords.length > 0)
  973   		{
  974   			StringBuffer coordsEnum = new StringBuffer(coords.length * 4);
  975   			coordsEnum.append(coords[0]);
  976   			for (int i = 1; i < coords.length; i++)
  977   			{
  978   				coordsEnum.append(',');
  979   				coordsEnum.append(coords[i]);
  980   			}
  981   
  982   			writer.write(" coords=\"" + coordsEnum + "\"");
  983   		}
  984   	}
  985   
  986   
  987   	protected void writeImageAreaHyperlink(JRPrintHyperlink hyperlink) throws IOException
  988   	{
  989   		String href = getHyperlinkURL(hyperlink);
  990   		if (href == null)
  991   		{
  992   			writer.write(" nohref=\"nohref\"");
  993   		}
  994   		else
  995   		{
  996   			writer.write(" href=\"" + href + "\"");
  997   
  998   			String target = getHyperlinkTarget(hyperlink);
  999   			if (target != null)
 1000   			{
 1001   				writer.write(" target=\"");
 1002   				writer.write(target);
 1003   				writer.write("\"");
 1004   			}
 1005   		}
 1006   
 1007   		if (hyperlink.getHyperlinkTooltip() != null)
 1008   		{
 1009   			writer.write(" title=\"");
 1010   			writer.write(JRStringUtil.xmlEncode(hyperlink.getHyperlinkTooltip()));
 1011   			writer.write("\"");
 1012   		}
 1013   	}
 1014   
 1015   
 1016   	/**
 1017   	 *
 1018   	 */
 1019   	public static String getImageName(JRPrintElementIndex printElementIndex)
 1020   	{
 1021   		return IMAGE_NAME_PREFIX + printElementIndex.toString();
 1022   	}
 1023   
 1024   
 1025   	/**
 1026   	 *
 1027   	 */
 1028   	public static JRPrintElementIndex getPrintElementIndex(String imageName)
 1029   	{
 1030   		if (!imageName.startsWith(IMAGE_NAME_PREFIX))
 1031   		{
 1032   			throw new JRRuntimeException("Invalid image name: " + imageName);
 1033   		}
 1034   
 1035   		return JRPrintElementIndex.parsePrintElementIndex(imageName.substring(IMAGE_NAME_PREFIX_LEGTH));
 1036   	}
 1037   
 1038   
 1039   	/**
 1040   	 *
 1041   	 */
 1042   	protected void exportFrame(TableBuilder tableBuilder, JRPrintFrame frame, JRExporterGridCell gridCell) throws IOException, JRException
 1043   	{
 1044   		tableBuilder.buildCellHeader(styleCache.getCellStyle(frame), gridCell.getColSpan(), gridCell.getRowSpan());
 1045   
 1046   		boolean appendBackcolor =
 1047   			frame.getMode() == JRElement.MODE_OPAQUE
 1048   			&& (backcolor == null || frame.getBackcolor().getRGB() != backcolor.getRGB());
 1049   
 1050   		if (appendBackcolor)
 1051   		{
 1052   			setBackcolor(frame.getBackcolor());
 1053   		}
 1054   
 1055   		try
 1056   		{
 1057   			JRGridLayout layout = gridCell.getLayout();
 1058   			JRPrintElementIndex frameIndex =
 1059   				new JRPrintElementIndex(
 1060   						reportIndex,
 1061   						pageIndex,
 1062   						gridCell.getWrapper().getAddress()
 1063   						);
 1064   			exportGrid(layout, frameIndex);
 1065   		}
 1066   		finally
 1067   		{
 1068   			if (appendBackcolor)
 1069   			{
 1070   				restoreBackcolor();
 1071   			}
 1072   		}
 1073   
 1074   		tableBuilder.buildCellFooter();
 1075   	}
 1076   
 1077   	/**
 1078   	 *
 1079   	 */
 1080   	protected void setBackcolor(Color color)
 1081   	{
 1082   		backcolorStack.addLast(backcolor);
 1083   
 1084   		backcolor = color;
 1085   	}
 1086   
 1087   
 1088   	protected void restoreBackcolor()
 1089   	{
 1090   		backcolor = (Color) backcolorStack.removeLast();
 1091   	}
 1092   
 1093   
 1094   	private float getXAlignFactor(JRPrintImage image)
 1095   	{
 1096   		float xalignFactor = 0f;
 1097   		switch (image.getHorizontalAlignment())
 1098   		{
 1099   			case JRAlignment.HORIZONTAL_ALIGN_RIGHT :
 1100   			{
 1101   				xalignFactor = 1f;
 1102   				break;
 1103   			}
 1104   			case JRAlignment.HORIZONTAL_ALIGN_CENTER :
 1105   			{
 1106   				xalignFactor = 0.5f;
 1107   				break;
 1108   			}
 1109   			case JRAlignment.HORIZONTAL_ALIGN_LEFT :
 1110   			default :
 1111   			{
 1112   				xalignFactor = 0f;
 1113   				break;
 1114   			}
 1115   		}
 1116   		return xalignFactor;
 1117   	}
 1118   
 1119   
 1120   	private float getYAlignFactor(JRPrintImage image)
 1121   	{
 1122   		float yalignFactor = 0f;
 1123   		switch (image.getVerticalAlignment())
 1124   		{
 1125   			case JRAlignment.VERTICAL_ALIGN_BOTTOM :
 1126   			{
 1127   				yalignFactor = 1f;
 1128   				break;
 1129   			}
 1130   			case JRAlignment.VERTICAL_ALIGN_MIDDLE :
 1131   			{
 1132   				yalignFactor = 0.5f;
 1133   				break;
 1134   			}
 1135   			case JRAlignment.VERTICAL_ALIGN_TOP :
 1136   			default :
 1137   			{
 1138   				yalignFactor = 0f;
 1139   				break;
 1140   			}
 1141   		}
 1142   		return yalignFactor;
 1143   	}
 1144   
 1145   	protected boolean startHyperlink(JRPrintHyperlink link, boolean isText) throws IOException
 1146   	{
 1147   		String href = getHyperlinkURL(link);
 1148   
 1149   		if (href != null)
 1150   		{
 1151   			if(isText)
 1152   			{
 1153   				tempBodyWriter.write("<text:a xlink:href=\"");
 1154   			}
 1155   			else
 1156   			{
 1157   				tempBodyWriter.write("<draw:a xlink:type=\"simple\" xlink:href=\"");
 1158   			}
 1159   			tempBodyWriter.write(href);
 1160   			tempBodyWriter.write("\"");
 1161   
 1162   
 1163   			String target = getHyperlinkTarget(link);
 1164   			if (target != null)
 1165   			{
 1166   				tempBodyWriter.write(" office:target-frame-name=\"");
 1167   				tempBodyWriter.write(target);
 1168   				tempBodyWriter.write("\"");
 1169   				if(target.equals("_blank"))
 1170   				{
 1171   					tempBodyWriter.write(" xlink:show=\"new\"");
 1172   				}
 1173   			}
 1174   /*
 1175    * tooltips are unavailable for the moment
 1176    *
 1177   			if (link.getHyperlinkTooltip() != null)
 1178   			{
 1179   				tempBodyWriter.write(" xlink:title=\"");
 1180   				tempBodyWriter.write(JRStringUtil.xmlEncode(link.getHyperlinkTooltip()));
 1181   				tempBodyWriter.write("\"");
 1182   			}
 1183   */
 1184   			tempBodyWriter.write(">");
 1185   		}
 1186   
 1187   		return href != null;
 1188   	}
 1189   
 1190   
 1191   	protected String getHyperlinkTarget(JRPrintHyperlink link)
 1192   	{
 1193   		String target = null;
 1194   		switch(link.getHyperlinkTarget())
 1195   		{
 1196   			case JRHyperlink.HYPERLINK_TARGET_SELF :
 1197   			{
 1198   				target = "_self";
 1199   				break;
 1200   			}
 1201   			case JRHyperlink.HYPERLINK_TARGET_BLANK :
 1202   			default :
 1203   			{
 1204   				target = "_blank";
 1205   				break;
 1206   			}
 1207   		}
 1208   		return target;
 1209   	}
 1210   
 1211   
 1212   	protected String getHyperlinkURL(JRPrintHyperlink link)
 1213   	{
 1214   		String href = null;
 1215   		JRHyperlinkProducer customHandler = getCustomHandler(link);
 1216   		if (customHandler == null)
 1217   		{
 1218   			switch(link.getHyperlinkType())
 1219   			{
 1220   				case JRHyperlink.HYPERLINK_TYPE_REFERENCE :
 1221   				{
 1222   					if (link.getHyperlinkReference() != null)
 1223   					{
 1224   						href = link.getHyperlinkReference();
 1225   					}
 1226   					break;
 1227   				}
 1228   				case JRHyperlink.HYPERLINK_TYPE_LOCAL_ANCHOR :
 1229   				{
 1230   					if (link.getHyperlinkAnchor() != null)
 1231   					{
 1232   						href = "#" + link.getHyperlinkAnchor();
 1233   					}
 1234   					break;
 1235   				}
 1236   				case JRHyperlink.HYPERLINK_TYPE_LOCAL_PAGE :
 1237   				{
 1238   					if (link.getHyperlinkPage() != null)
 1239   					{
 1240   						href = "#" + JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + link.getHyperlinkPage().toString();
 1241   					}
 1242   					break;
 1243   				}
 1244   				case JRHyperlink.HYPERLINK_TYPE_REMOTE_ANCHOR :
 1245   				{
 1246   					if (
 1247   						link.getHyperlinkReference() != null &&
 1248   						link.getHyperlinkAnchor() != null
 1249   						)
 1250   					{
 1251   						href = link.getHyperlinkReference() + "#" + link.getHyperlinkAnchor();
 1252   					}
 1253   					break;
 1254   				}
 1255   				case JRHyperlink.HYPERLINK_TYPE_REMOTE_PAGE :
 1256   				{
 1257   					if (
 1258   						link.getHyperlinkReference() != null &&
 1259   						link.getHyperlinkPage() != null
 1260   						)
 1261   					{
 1262   						href = link.getHyperlinkReference() + "#" + JR_PAGE_ANCHOR_PREFIX + "0_" + link.getHyperlinkPage().toString();
 1263   					}
 1264   					break;
 1265   				}
 1266   				case JRHyperlink.HYPERLINK_TYPE_NONE :
 1267   				default :
 1268   				{
 1269   					break;
 1270   				}
 1271   			}
 1272   		}
 1273   		else
 1274   		{
 1275   			href = customHandler.getHyperlink(link);
 1276   		}
 1277   
 1278   		return href;
 1279   	}
 1280   
 1281   
 1282   	protected JRHyperlinkProducer getCustomHandler(JRPrintHyperlink link)
 1283   	{
 1284   		return hyperlinkProducerFactory == null ? null : hyperlinkProducerFactory.getHandler(link.getLinkType());
 1285   	}
 1286   
 1287   
 1288   	protected void endHyperlink(boolean isText) throws IOException
 1289   	{
 1290   		if(isText)
 1291   			tempBodyWriter.write("</text:a>");
 1292   		else
 1293   			tempBodyWriter.write("</draw:a>");
 1294   	}
 1295   
 1296   	protected void insertPageAnchor() throws IOException
 1297   	{
 1298   		if(startPage)
 1299   		{
 1300   			tempBodyWriter.write("<text:bookmark text:name=\"");
 1301   			tempBodyWriter.write(JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + (pageIndex + 1));
 1302   			tempBodyWriter.write("\"/>\n");
 1303   			startPage = false;
 1304   		}
 1305   	}
 1306   
 1307   }
 1308   

Save This Page
Home » jasperreports-3.0.0-project » net.sf.jasperreports.engine.export.oasis » [javadoc | source]