/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2009 Jaspersoft Corporation. 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 <http://www.gnu.org/licenses/>.
*/
/*
* Contributors:
* Greg Hilton
*/
package net.sf.jasperreports.engine.export;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.jasperreports.engine.JRAbstractExporter;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JRFont;
import net.sf.jasperreports.engine.JRGenericPrintElement;
import net.sf.jasperreports.engine.JRPen;
import net.sf.jasperreports.engine.JRPrintElement;
import net.sf.jasperreports.engine.JRPrintEllipse;
import net.sf.jasperreports.engine.JRPrintFrame;
import net.sf.jasperreports.engine.JRPrintGraphicElement;
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.JRStyledTextAttributeSelector;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.base.JRBasePrintText;
import net.sf.jasperreports.engine.type.HorizontalAlignEnum;
import net.sf.jasperreports.engine.type.RotationEnum;
import net.sf.jasperreports.engine.type.VerticalAlignEnum;
import net.sf.jasperreports.engine.util.JRProperties;
import net.sf.jasperreports.engine.util.JRStyledText;
/**
* @author Teodor Danciu (teodord@users.sourceforge.net)
* @version $Id: JRXlsAbstractExporter.java 3842 2010-06-01 10:35:17Z teodord $
*/
public abstract class JRXlsAbstractExporter extends JRAbstractExporter
{
protected static final String XLS_EXPORTER_PROPERTIES_PREFIX = JRProperties.PROPERTY_PREFIX + "export.xls.";
protected static class TextAlignHolder
{
public final HorizontalAlignEnum horizontalAlignment;
public final VerticalAlignEnum verticalAlignment;
public final RotationEnum rotation;
public TextAlignHolder(HorizontalAlignEnum horizontalAlignment, VerticalAlignEnum verticalAlignment, RotationEnum rotation)
{
this.horizontalAlignment = horizontalAlignment;
this.verticalAlignment = verticalAlignment;
this.rotation = rotation;
}
}
/**
*
*/
protected List loadedFonts = new ArrayList();
/**
*
*/
protected boolean isOnePagePerSheet;
protected boolean isRemoveEmptySpaceBetweenRows;
protected boolean isRemoveEmptySpaceBetweenColumns;
protected boolean isWhitePageBackground;
protected boolean isAutoDetectCellType = false;
protected boolean isDetectCellType;
protected boolean isFontSizeFixEnabled;
protected boolean isImageBorderFixEnabled;
protected boolean isIgnoreGraphics;
protected boolean isCollapseRowSpan;
protected boolean isIgnoreCellBorder;
protected boolean isIgnoreCellBackground;
protected int maxRowsPerSheet;
protected String[] sheetNames = null;
protected JRExportProgressMonitor progressMonitor = null;
protected int reportIndex = 0;
protected int pageIndex = 0;
/**
* @deprecated
*/
protected Map fontMap = null;
/**
*
*/
protected JRFont defaultFont = null;
/**
* used for counting the total number of sheets
*/
protected int sheetIndex = 0;
/**
* used when indexing the identical sheet generated names with ordering numbers;
* contains sheet names as keys and the number of occurrences of each sheet name as values
*/
protected Map sheetNamesMap = null;
protected String currentSheetName = null;
protected boolean isIgnorePageMargins;
/**
*
*/
protected JRFont getDefaultFont()
{
return defaultFont;
}
/**
*
*/
public void exportReport() throws JRException
{
progressMonitor = (JRExportProgressMonitor)parameters.get(JRExporterParameter.PROGRESS_MONITOR);
/* */
setOffset();
try
{
/* */
setExportContext();
/* */
setInput();
if (!parameters.containsKey(JRExporterParameter.FILTER))
{
filter = createFilter(XLS_EXPORTER_PROPERTIES_PREFIX);
}
/* */
if (!isModeBatch)
{
setPageRange();
}
setParameters();
OutputStream os = (OutputStream)parameters.get(JRExporterParameter.OUTPUT_STREAM);
if (os != null)
{
exportReportToStream(os);
}
else
{
File destFile = (File)parameters.get(JRExporterParameter.OUTPUT_FILE);
if (destFile == null)
{
String fileName = (String)parameters.get(JRExporterParameter.OUTPUT_FILE_NAME);
if (fileName != null)
{
destFile = new File(fileName);
}
else
{
throw new JRException("No output specified for the exporter.");
}
}
try
{
os = new FileOutputStream(destFile);
exportReportToStream(os);
os.flush();
}
catch (IOException e)
{
throw new JRException("Error trying to export to file : " + destFile, e);
}
finally
{
if (os != null)
{
try
{
os.close();
}
catch(IOException e)
{
}
}
}
}
}
finally
{
resetExportContext();
}
}
protected void setParameters()
{
isOnePagePerSheet =
getBooleanParameter(
JRXlsAbstractExporterParameter.IS_ONE_PAGE_PER_SHEET,
JRXlsAbstractExporterParameter.PROPERTY_ONE_PAGE_PER_SHEET,
false
);
isRemoveEmptySpaceBetweenRows =
getBooleanParameter(
JRXlsAbstractExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,
JRXlsAbstractExporterParameter.PROPERTY_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,
false
);
isRemoveEmptySpaceBetweenColumns =
getBooleanParameter(
JRXlsAbstractExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_COLUMNS,
JRXlsAbstractExporterParameter.PROPERTY_REMOVE_EMPTY_SPACE_BETWEEN_COLUMNS,
false
);
isWhitePageBackground =
getBooleanParameter(
JRXlsAbstractExporterParameter.IS_WHITE_PAGE_BACKGROUND,
JRXlsAbstractExporterParameter.PROPERTY_WHITE_PAGE_BACKGROUND,
false
);
setBackground();
Boolean isAutoDetectCellTypeParameter = (Boolean)parameters.get(JRXlsAbstractExporterParameter.IS_AUTO_DETECT_CELL_TYPE);
if (isAutoDetectCellTypeParameter != null)
{
isAutoDetectCellType = isAutoDetectCellTypeParameter.booleanValue();
}
isDetectCellType =
getBooleanParameter(
JRXlsAbstractExporterParameter.IS_DETECT_CELL_TYPE,
JRXlsAbstractExporterParameter.PROPERTY_DETECT_CELL_TYPE,
false
);
isFontSizeFixEnabled =
getBooleanParameter(
JRXlsAbstractExporterParameter.IS_FONT_SIZE_FIX_ENABLED,
JRXlsAbstractExporterParameter.PROPERTY_FONT_SIZE_FIX_ENABLED,
false
);
isImageBorderFixEnabled =
getBooleanParameter(
JRXlsAbstractExporterParameter.IS_IMAGE_BORDER_FIX_ENABLED,
JRXlsAbstractExporterParameter.PROPERTY_IMAGE_BORDER_FIX_ENABLED,
false
);
isIgnoreGraphics =
getBooleanParameter(
JRXlsAbstractExporterParameter.IS_IGNORE_GRAPHICS,
JRXlsAbstractExporterParameter.PROPERTY_IGNORE_GRAPHICS,
false
);
isCollapseRowSpan =
getBooleanParameter(
JRXlsAbstractExporterParameter.IS_COLLAPSE_ROW_SPAN,
JRXlsAbstractExporterParameter.PROPERTY_COLLAPSE_ROW_SPAN,
false
);
isIgnoreCellBorder =
getBooleanParameter(
JRXlsAbstractExporterParameter.IS_IGNORE_CELL_BORDER,
JRXlsAbstractExporterParameter.PROPERTY_IGNORE_CELL_BORDER,
false
);
isIgnoreCellBackground =
getBooleanParameter(
JRXlsAbstractExporterParameter.IS_IGNORE_CELL_BACKGROUND,
JRXlsAbstractExporterParameter.PROPERTY_IGNORE_CELL_BACKGROUND,
false
);
String[] sheetNamesArray =
getStringArrayParameter(
JRXlsAbstractExporterParameter.SHEET_NAMES,
JRXlsAbstractExporterParameter.PROPERTY_SHEET_NAMES_PREFIX
);
if (sheetNamesArray != null)
{
List sheetNamesList = new ArrayList();
for(int i = 0; i < sheetNamesArray.length; i++)
{
String[] currentSheetNamesArray = sheetNamesArray[i].split("/");
for(int j = 0; j < currentSheetNamesArray.length; j++)
{
sheetNamesList.add(currentSheetNamesArray[j]);
}
}
sheetNames = (String[]) sheetNamesList.toArray(new String[sheetNamesList.size()]);
}
fontMap = (Map) parameters.get(JRExporterParameter.FONT_MAP);
setHyperlinkProducerFactory();
maxRowsPerSheet =
getIntegerParameter(
JRXlsAbstractExporterParameter.MAXIMUM_ROWS_PER_SHEET,
JRXlsAbstractExporterParameter.PROPERTY_MAXIMUM_ROWS_PER_SHEET,
0
);
isIgnorePageMargins =
getBooleanParameter(
JRExporterParameter.IGNORE_PAGE_MARGINS,
JRExporterParameter.PROPERTY_IGNORE_PAGE_MARGINS,
false
);
}
protected abstract void setBackground();
protected void exportReportToStream(OutputStream os) throws JRException
{
openWorkbook(os);
sheetNamesMap = new HashMap();
sheetNamesMap.put("Page", Integer.valueOf(0)); // in order to skip first sheet name that would have no index
for(reportIndex = 0; reportIndex < jasperPrintList.size(); reportIndex++)
{
setJasperPrint((JasperPrint)jasperPrintList.get(reportIndex));
defaultFont = new JRBasePrintText(jasperPrint.getDefaultStyleProvider());
List pages = jasperPrint.getPages();
if (pages != null && pages.size() > 0)
{
if (isModeBatch)
{
startPageIndex = 0;
endPageIndex = pages.size() - 1;
}
if (isOnePagePerSheet)
{
for(pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++)
{
if (Thread.interrupted())
{
throw new JRException("Current thread interrupted.");
}
JRPrintPage page = (JRPrintPage)pages.get(pageIndex);
if (sheetNames != null && sheetIndex < sheetNames.length)
{
createSheet(getSheetName(sheetNames[sheetIndex]));
}
else
{
createSheet(getSheetName("Page"));
}
// we need to count all sheets generated for all exported documents
sheetIndex++;
/* */
exportPage(page, /*xCuts*/null, /*startRow*/0);
}
}
else
{
// Create the sheet before looping.
if (sheetNames != null && sheetIndex < sheetNames.length)
{
createSheet(getSheetName(sheetNames[sheetIndex]));
}
else
{
createSheet(getSheetName(jasperPrint.getName()));
}
// we need to count all sheets generated for all exported documents
sheetIndex++;
/*
* Make a pass and calculate the X cuts for all pages on this sheet.
* The Y cuts can be calculated as each page is exported.
*/
CutsInfo xCuts =
JRGridLayout.calculateXCuts(
getNature(), pages, startPageIndex, endPageIndex,
jasperPrint.getPageWidth(), globalOffsetX
);
//clear the filter's internal cache that might have built up
if (filter instanceof ResetableExporterFilter)
{
((ResetableExporterFilter)filter).reset();
}
int startRow = 0;
for(pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++)
{
if (Thread.interrupted())
{
throw new JRException("Current thread interrupted.");
}
JRPrintPage page = (JRPrintPage)pages.get(pageIndex);
startRow = exportPage(page, xCuts, startRow);
}
if (isRemoveEmptySpaceBetweenColumns)
{
removeEmptyColumns(xCuts);
}
}
}
}
closeWorkbook(os);
}
/**
*
* @return the number of rows added.
*/
protected int exportPage(JRPrintPage page, CutsInfo xCuts, int startRow) throws JRException
{
JRGridLayout layout =
new JRGridLayout(
getNature(),
page.getElements(),
jasperPrint.getPageWidth(),
jasperPrint.getPageHeight(),
globalOffsetX,
globalOffsetY,
xCuts
);
JRExporterGridCell grid[][] = layout.getGrid();
boolean createXCuts = (xCuts == null);
if (createXCuts)
{
xCuts = layout.getXCuts();
setColumnWidths(xCuts);
}
if (startRow == 0)
{
setColumnWidths(xCuts);
}
CutsInfo yCuts = layout.getYCuts();
int skippedRows = 0;
int rowIndex = startRow;
for(int y = 0; y < grid.length; y++)
{
rowIndex = y - skippedRows + startRow;
//if number of rows is too large a new sheet is created and populated with remaining rows
if(
(maxRowsPerSheet > 0 && rowIndex >= maxRowsPerSheet)
|| yCuts.isBreak(y)
)
{
createSheet(getSheetName(currentSheetName));
setColumnWidths(xCuts);
startRow = 0;
rowIndex = 0;
skippedRows = y;
}
if (
yCuts.isCutNotEmpty(y)
|| ((!isRemoveEmptySpaceBetweenRows || yCuts.isCutSpanned(y))
&& !isCollapseRowSpan)
)
{
JRExporterGridCell[] gridRow = grid[y];
int emptyCellColSpan = 0;
int emptyCellWidth = 0;
setRowHeight(
rowIndex,
isCollapseRowSpan
? JRGridLayout.getMaxRowHeight(gridRow)
: JRGridLayout.getRowHeight(gridRow)
);
int emptyCols = 0;
for(int colIndex = 0; colIndex < gridRow.length; colIndex++)
{
emptyCols += (isRemoveEmptySpaceBetweenColumns && (!(xCuts.isCutNotEmpty(colIndex) || xCuts.isCutSpanned(colIndex))) ? 1 : 0);
JRExporterGridCell gridCell = gridRow[colIndex];
setCell(gridCell, colIndex, rowIndex);
if (gridCell.getType() == JRExporterGridCell.TYPE_OCCUPIED_CELL)
{
if (emptyCellColSpan > 0)
{
//tableHelper.exportEmptyCell(gridCell, emptyCellColSpan);
emptyCellColSpan = 0;
emptyCellWidth = 0;
}
addOccupiedCell((OccupiedGridCell)gridCell, colIndex, rowIndex);
}
else if(gridCell.getWrapper() != null)
{
if (emptyCellColSpan > 0)
{
// if (emptyCellColSpan > 1)
// {
// //sbuffer.append(" colspan=" + emptyCellColSpan);
// //sheet.addMergedRegion(new Region(y, (short)(x - emptyCellColSpan - 1), y, (short)(x - 1)));
// }
emptyCellColSpan = 0;
emptyCellWidth = 0;
}
JRPrintElement element = gridCell.getWrapper().getElement();
if (element instanceof JRPrintLine)
{
exportLine((JRPrintLine)element, gridCell, colIndex, rowIndex);
}
else if (element instanceof JRPrintRectangle)
{
exportRectangle((JRPrintRectangle)element, gridCell, colIndex, rowIndex);
}
else if (element instanceof JRPrintEllipse)
{
exportRectangle((JRPrintEllipse)element, gridCell, colIndex, rowIndex);
}
else if (element instanceof JRPrintImage)
{
exportImage((JRPrintImage) element, gridCell, colIndex, rowIndex, emptyCols);
}
else if (element instanceof JRPrintText)
{
exportText((JRPrintText)element, gridCell, colIndex, rowIndex);
}
else if (element instanceof JRPrintFrame)
{
exportFrame((JRPrintFrame) element, gridCell, colIndex, y);//FIXME rowIndex?
}
else if (element instanceof JRGenericPrintElement)
{
exportGenericElement((JRGenericPrintElement) element, gridCell, colIndex, rowIndex, emptyCols);
}
//colIndex += gridCell.getColSpan() - 1;
}
else
{
emptyCellColSpan++;
emptyCellWidth += gridCell.getWidth();
addBlankCell(gridCell, colIndex, rowIndex);
}
}
// if (emptyCellColSpan > 0)
// {
// if (emptyCellColSpan > 1)
// {
// //sbuffer.append(" colspan=" + emptyCellColSpan);
// //sheet.addMergedRegion(new Region(y, (short)x, y, (short)(x + emptyCellColSpan - 1)));
// }
// }
//increment row index to return proper value
++rowIndex;
}
else
{
skippedRows++;
// setRowHeight(y, 0);
//
// for(int x = 0; x < grid[y].length; x++)
// {
// addBlankCell(x, y);
// setCell(x, y);
// }
}
}
if (createXCuts && isRemoveEmptySpaceBetweenColumns)
{
removeEmptyColumns(xCuts);
}
if (progressMonitor != null)
{
progressMonitor.afterPageExport();
}
// Return the number of rows added
return rowIndex;
}
protected void setColumnWidths(CutsInfo xCuts)
{
for(int col = 0; col < xCuts.size() - 1; col++)
{
if (!isRemoveEmptySpaceBetweenColumns || (xCuts.isCutNotEmpty(col) || xCuts.isCutSpanned(col)))
{
int width = xCuts.getCut(col + 1) - xCuts.getCut(col);
setColumnWidth(col, width);
}
}
}
protected void removeEmptyColumns(CutsInfo xCuts)
{
for(int col = xCuts.size() - 1; col >= 0; col--)
{
if (!(xCuts.isCutNotEmpty(col) || xCuts.isCutSpanned(col)))
{
removeColumn(col);
}
}
}
/**
*
*/
protected JRStyledText getStyledText(JRPrintText textElement)
{
return textElement.getFullStyledText(JRStyledTextAttributeSelector.NONE);
}
/**
*
*/
protected static TextAlignHolder getTextAlignHolder(JRPrintText textElement)
{
HorizontalAlignEnum horizontalAlignment;
VerticalAlignEnum verticalAlignment;
RotationEnum rotation = textElement.getRotationValue();
switch (textElement.getRotationValue())
{
case LEFT :
{
switch (textElement.getHorizontalAlignmentValue())
{
case LEFT :
{
verticalAlignment = VerticalAlignEnum.BOTTOM;
break;
}
case CENTER :
{
verticalAlignment = VerticalAlignEnum.MIDDLE;
break;
}
case RIGHT :
{
verticalAlignment = VerticalAlignEnum.TOP;
break;
}
case JUSTIFIED :
{
verticalAlignment = VerticalAlignEnum.JUSTIFIED;
break;
}
default :
{
verticalAlignment = VerticalAlignEnum.BOTTOM;
}
}
switch (textElement.getVerticalAlignmentValue())
{
case TOP :
{
horizontalAlignment = HorizontalAlignEnum.LEFT;
break;
}
case MIDDLE :
{
horizontalAlignment = HorizontalAlignEnum.CENTER;
break;
}
case BOTTOM :
{
horizontalAlignment = HorizontalAlignEnum.RIGHT;
break;
}
default :
{
horizontalAlignment = HorizontalAlignEnum.LEFT;
}
}
break;
}
case RIGHT :
{
switch (textElement.getHorizontalAlignmentValue())
{
case LEFT :
{
verticalAlignment = VerticalAlignEnum.TOP;
break;
}
case CENTER :
{
verticalAlignment = VerticalAlignEnum.MIDDLE;
break;
}
case RIGHT :
{
verticalAlignment = VerticalAlignEnum.BOTTOM;
break;
}
case JUSTIFIED :
{
verticalAlignment = VerticalAlignEnum.JUSTIFIED;
break;
}
default :
{
verticalAlignment = VerticalAlignEnum.TOP;
}
}
switch (textElement.getVerticalAlignmentValue())
{
case TOP :
{
horizontalAlignment = HorizontalAlignEnum.RIGHT;
break;
}
case MIDDLE :
{
horizontalAlignment = HorizontalAlignEnum.CENTER;
break;
}
case BOTTOM :
{
horizontalAlignment = HorizontalAlignEnum.LEFT;
break;
}
default :
{
horizontalAlignment = HorizontalAlignEnum.RIGHT;
}
}
break;
}
case UPSIDE_DOWN:
case NONE :
default :
{
horizontalAlignment = textElement.getHorizontalAlignmentValue();
verticalAlignment = textElement.getVerticalAlignmentValue();
}
}
return new TextAlignHolder(horizontalAlignment, verticalAlignment, rotation);
}
/**
*
*/
protected int getImageBorderCorrection(JRPen pen)
{
float lineWidth = pen.getLineWidth().floatValue();
if (lineWidth > 0f)
{
if (lineWidth >= 2f)
{
return 2;
}
return 1;
}
return isImageBorderFixEnabled ? 1 : 0;
}
/**
*
*/
private String getSheetName(String sheetName)
{
currentSheetName = sheetName;
// sheet names must be unique
if(!sheetNamesMap.containsKey(sheetName))
{
// first time this sheet name is found;
sheetNamesMap.put(sheetName, Integer.valueOf(1));
return sheetName.length() > 31 ? sheetName.substring(0, 31) : sheetName;
}
int currentIndex = ((Integer)sheetNamesMap.get(sheetName)).intValue() + 1;
sheetNamesMap.put(sheetName, Integer.valueOf(currentIndex));
String name = sheetName + " " + currentIndex;
if(name.length() > 31)
{
String crtIndex = String.valueOf(currentIndex);
name = (sheetName + " ").substring(0, 31-crtIndex.length()) + crtIndex;
}
return name;
}
// Berechnungsvorschriften f�r die DIN Formate A, B, und C.
// Die Angabe der Breite/H�he erfolgt in [mm].
protected final int calculateWidthForDinAN(int n)
{
return (int) (Math.pow(2.0, (-0.25 - (n / 2.0))) * 1000.0);
}
protected final int calculateHeightForDinAN(int n)
{
return (int) (Math.pow(2.0, (0.25 - (n / 2.0))) * 1000.0);
}
protected final int calculateWidthForDinBN(int n)
{
return (int) (Math.pow(2.0, -(n / 2.0)) * 1000.0);
}
protected final int calculateHeightForDinBN(int n)
{
return (int) (Math.pow(2.0, (0.5 - (n / 2.0))) * 1000.0);
}
protected final int calculateWidthForDinCN(int n)
{
return (int) (Math.pow(2.0, (-0.125 - (n / 2.0))) * 1000.0);
}
protected final int calculateHeightForDinCN(int n)
{
return (int) (Math.pow(2.0, (0.375 - (n / 2.0))) * 1000.0);
}
protected abstract ExporterNature getNature();
protected abstract void openWorkbook(OutputStream os) throws JRException;
protected abstract void createSheet(String name);
protected abstract void closeWorkbook(OutputStream os) throws JRException;
protected abstract void setColumnWidth(int col, int width);
protected abstract void removeColumn(int col);
protected abstract void setRowHeight(int rowIndex, int lastRowHeight) throws JRException;
protected abstract void setCell(JRExporterGridCell gridCell, int colIndex, int rowIndex);
protected abstract void addBlankCell(JRExporterGridCell gridCell, int colIndex, int rowIndex) throws JRException;
protected abstract void addOccupiedCell(OccupiedGridCell occupiedGridCell, int colIndex, int rowIndex) throws JRException;
protected abstract void exportText(JRPrintText text, JRExporterGridCell cell, int colIndex, int rowIndex) throws JRException;
protected abstract void exportImage(JRPrintImage image, JRExporterGridCell cell, int colIndex, int rowIndex, int emptyCols) throws JRException;
protected abstract void exportRectangle(JRPrintGraphicElement element, JRExporterGridCell cell, int colIndex, int rowIndex) throws JRException;
protected abstract void exportLine(JRPrintLine line, JRExporterGridCell cell, int colIndex, int rowIndex) throws JRException;
protected abstract void exportFrame(JRPrintFrame frame, JRExporterGridCell cell, int colIndex, int rowIndex) throws JRException;
protected abstract void exportGenericElement(JRGenericPrintElement element, JRExporterGridCell cell, int colIndex, int rowIndex, int emptyCols) throws JRException;
}