/*
* 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/>.
*/
package net.sf.jasperreports.engine.export.xmlss;
import java.awt.Color;
import java.awt.Font;
import java.awt.font.TextAttribute;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.AttributedCharacterIterator;
import java.util.HashMap;
import java.util.LinkedList;
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.JRPrintElement;
import net.sf.jasperreports.engine.JRPrintElementIndex;
import net.sf.jasperreports.engine.JRPrintFrame;
import net.sf.jasperreports.engine.JRPrintHyperlink;
import net.sf.jasperreports.engine.JRPrintPage;
import net.sf.jasperreports.engine.JRPrintText;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.base.JRBasePrintText;
import net.sf.jasperreports.engine.export.CutsInfo;
import net.sf.jasperreports.engine.export.ExporterNature;
import net.sf.jasperreports.engine.export.GenericElementHandlerEnviroment;
import net.sf.jasperreports.engine.export.JRExportProgressMonitor;
import net.sf.jasperreports.engine.export.JRExporterGridCell;
import net.sf.jasperreports.engine.export.JRGridLayout;
import net.sf.jasperreports.engine.export.JRHyperlinkProducer;
import net.sf.jasperreports.engine.export.JRXlsAbstractExporterParameter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.export.ResetableExporterFilter;
import net.sf.jasperreports.engine.export.data.BooleanTextValue;
import net.sf.jasperreports.engine.export.data.DateTextValue;
import net.sf.jasperreports.engine.export.data.NumberTextValue;
import net.sf.jasperreports.engine.export.data.TextValue;
import net.sf.jasperreports.engine.type.OrientationEnum;
import net.sf.jasperreports.engine.util.JRColorUtil;
import net.sf.jasperreports.engine.util.JRProperties;
import net.sf.jasperreports.engine.util.JRStringUtil;
import net.sf.jasperreports.engine.util.JRStyledText;
/**
* Exports a JasperReports document to XML Spreadsheet format. It has character output type and exports the document to a
* grid-based layout.
* @author sanda zaharia (shertage@users.sourceforge.net)
* @version $Id: JRXmlssExporter.java 3675 2010-04-02 08:58:23Z shertage $
*/
public class JRXmlssExporter extends JRAbstractExporter
{
/**
* The exporter key, as used in
* {@link GenericElementHandlerEnviroment#getHandler(net.sf.jasperreports.engine.JRGenericElementType, String)}.
*/
public static final String XMLSS_EXPORTER_KEY = JRProperties.PROPERTY_PREFIX + "xmlss";
private static final String XMLSS_EXPORTER_PROPERTIES_PREFIX = JRProperties.PROPERTY_PREFIX + "export.xmlss.";
/**
*
*/
protected static final String JR_PAGE_ANCHOR_PREFIX = "JR_PAGE_ANCHOR_";
/**
*
*/
protected static final String HORIZONTAL_ALIGN_LEFT = "start";
protected static final String HORIZONTAL_ALIGN_RIGHT = "end";
protected static final String HORIZONTAL_ALIGN_CENTER = "center";
protected static final String HORIZONTAL_ALIGN_JUSTIFY = "justified";
/**
*
*/
protected static final String VERTICAL_ALIGN_TOP = "top";
protected static final String VERTICAL_ALIGN_MIDDLE = "middle";
protected static final String VERTICAL_ALIGN_BOTTOM = "bottom";
public static final String IMAGE_NAME_PREFIX = "img_";
protected static final int IMAGE_NAME_PREFIX_LEGTH = IMAGE_NAME_PREFIX.length();
protected static final String[] PAGE_LAYOUT = new String[] {"Portrait", "Portrait", "Landscape"};
/**
*
*/
protected Writer tempBodyWriter = null;
protected Writer tempStyleWriter = null;
protected JRExportProgressMonitor progressMonitor = null;
protected Map rendererToImagePathMap = null;
protected Map imageMaps;
protected List imagesToProcess = null;
protected int reportIndex = 0;
protected int pageIndex = 0;
protected int tableIndex = 0;
protected boolean startPage;
/**
*
*/
protected String encoding = null;
/**
*
*/
protected boolean isWrapBreakWord = false;
/**
* @deprecated
*/
protected Map fontMap = null;
private LinkedList backcolorStack;
private Color backcolor;
private XmlssStyleCache styleCache = null;
protected ExporterNature nature = null;
protected File destFile = null;
/**
*
*/
protected boolean isOnePagePerSheet;
protected boolean isRemoveEmptySpaceBetweenRows;
protected boolean isRemoveEmptySpaceBetweenColumns;
protected boolean isWhitePageBackground;
protected boolean isAutoDetectCellType = false;
protected boolean isDetectCellType;
protected boolean isFontSizeFixEnabled;
protected boolean isIgnoreGraphics;
protected boolean isCollapseRowSpan;
protected boolean isIgnoreCellBorder;
protected boolean isIgnorePageMargins;
protected int maxRowsPerSheet;
protected String[] sheetNames = 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 occurences of each sheet name as values
*/
protected Map sheetNamesMap = null;
protected String currentSheetName = null;
/**
*
*/
protected JRFont defaultFont = null;
protected Map formatPatternsMap = null;
protected OrientationEnum pageOrientation;
public JRXmlssExporter()
{
backcolorStack = new LinkedList();
backcolor = null;
}
/**
*
*/
public void exportReport() throws JRException
{
progressMonitor = (JRExportProgressMonitor)parameters.get(JRExporterParameter.PROGRESS_MONITOR);
/* */
setOffset();
try
{
/* */
setExportContext();
/* */
setInput();
if (!parameters.containsKey(JRExporterParameter.FILTER))
{
filter = createFilter(XMLSS_EXPORTER_PROPERTIES_PREFIX);
}
/* */
if (!isModeBatch)
{
setPageRange();
}
setParameters();
nature = new JRXmlssExporterNature(filter, isIgnorePageMargins);
pageOrientation = jasperPrint.getOrientationValue();
StringBuffer sb = (StringBuffer)parameters.get(JRExporterParameter.OUTPUT_STRING_BUFFER);
if (sb != null)
{
StringBuffer buffer = exportReportToBuffer();
sb.append(buffer.toString());
}
else
{
Writer outWriter = (Writer)parameters.get(JRExporterParameter.OUTPUT_WRITER);
if (outWriter != null)
{
try
{
exportReportToStream(outWriter);
}
catch (IOException e)
{
throw new JRException("Error writing to writer : " + jasperPrint.getName(), e);
}
}
else
{
OutputStream os = (OutputStream)parameters.get(JRExporterParameter.OUTPUT_STREAM);
if (os != null)
{
try
{
exportReportToStream(new OutputStreamWriter(os, encoding));
}
catch (Exception e)
{
throw new JRException("Error writing to OutputStream : " + jasperPrint.getName(), e);
}
}
else
{
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.");
}
}
exportReportToFile();
}
}
}
}
finally
{
resetExportContext();
}
}
/**
*
*/
protected void exportReportToFile() throws JRException
{
Writer writer = null;
try
{
OutputStream fileOutputStream = new FileOutputStream(destFile);
writer = new BufferedWriter(new OutputStreamWriter(fileOutputStream, encoding));
exportReportToStream(writer);
}
catch (IOException e)
{
throw new JRException("Error writing to file : " + destFile, e);
}
finally
{
if (writer != null)
{
try
{
writer.close();
}
catch(IOException e)
{
}
}
}
}
/**
*
*/
protected StringBuffer exportReportToBuffer() throws JRException
{
StringWriter buffer = new StringWriter();
try
{
exportReportToStream(buffer);
}
catch (IOException e)
{
throw new JRException("Error while exporting report to buffer", e);
}
return buffer.getBuffer();
}
/**
*
*/
protected void exportReportToStream(Writer writer) throws JRException, IOException
{
tempBodyWriter = new StringWriter();
tempStyleWriter = new StringWriter();
styleCache = new XmlssStyleCache(tempStyleWriter, fontMap);
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(int 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)
{
tempBodyWriter.write("<Worksheet ss:Name=\""+getSheetName(sheetNames[sheetIndex])+"\">\n");
}
else
{
tempBodyWriter.write("<Worksheet ss:Name=\""+getSheetName("Page")+"\">\n");
}
// we need to count all sheets generated for all exported documents
sheetIndex++;
tempBodyWriter.write("<Table>\n");
exportPage(page, null, 0, null, true);
tempBodyWriter.write("</Table>\n");
closeWorksheet();
}
}
else
{
// Create the sheet before looping.
if (sheetNames != null && sheetIndex < sheetNames.length)
{
tempBodyWriter.write("<Worksheet ss:Name=\""+getSheetName(sheetNames[sheetIndex])+"\">\n");
}
else
{
tempBodyWriter.write("<Worksheet ss:Name=\""+getSheetName(jasperPrint.getName())+"\">\n");
}
tempBodyWriter.write("<Table>\n");
// 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(
nature, 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(int 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, null, pageIndex == startPageIndex);
}
// if (isRemoveEmptySpaceBetweenColumns)
// {
// //FIXME: to remove empty columns when isRemoveEmptySpaceBetweenColumns
// //removeEmptyColumns(xCuts);
// }
tempBodyWriter.write("</Table>\n");
closeWorksheet();
}
}
}
tempBodyWriter.flush();
tempStyleWriter.flush();
tempBodyWriter.close();
tempStyleWriter.close();
/* */
XmlssContentBuilder xmlssContentBuilder =
new XmlssContentBuilder(
writer,
tempStyleWriter,
tempBodyWriter
);
xmlssContentBuilder.build();
}
/**
*
* @return the number of rows added.
*/
protected int exportPage(JRPrintPage page, CutsInfo xCuts, int startRow, JRPrintElementIndex frameIndex, boolean isNewSheet) throws JRException
{
try
{
JRGridLayout layout =
new JRGridLayout(
nature,
page.getElements(),
jasperPrint.getPageWidth(),
jasperPrint.getPageHeight(),
globalOffsetX,
globalOffsetY,
xCuts
);
JRExporterGridCell grid[][] = layout.getGrid();
boolean createXCuts = (xCuts == null);
if (createXCuts)
{
xCuts = layout.getXCuts();
}
CutsInfo yCuts = layout.getYCuts();
int skippedRows = 0;
int rowIndex = startRow;
XmlssTableBuilder tableBuilder = frameIndex == null
? new XmlssTableBuilder(reportIndex, pageIndex, tempBodyWriter, tempStyleWriter)
: new XmlssTableBuilder(frameIndex.toString(), tempBodyWriter, tempStyleWriter);
if(isNewSheet)
{
buildColumns(xCuts, tableBuilder);
}
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)
{
tableBuilder.buildTableFooter();
closeWorksheet();
tempBodyWriter.write("<Worksheet ss:Name=\""+getSheetName(currentSheetName)+"\">\n");
tableBuilder.buildTableHeader();
buildColumns(xCuts, tableBuilder);
startRow = 0;
rowIndex = 0;
skippedRows = y;
}
if (
yCuts.isCutNotEmpty(y)
|| ((!isRemoveEmptySpaceBetweenRows || yCuts.isCutSpanned(y))
&& !isCollapseRowSpan)
)
{
JRExporterGridCell[] gridRow = grid[y];
int emptyCellColSpan = 0;
int emptyCellRowSpan = 0;
int emptyCellWidth = 0;
int rowHeight = isCollapseRowSpan ? JRGridLayout.getMaxRowHeight(gridRow) : JRGridLayout.getRowHeight(gridRow);
tableBuilder.buildRowHeader(rowIndex, rowHeight);
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];
if(gridCell.getWrapper() != null)
{
if (emptyCellColSpan > 0)
{
tableBuilder.buildEmptyCell(emptyCellColSpan, emptyCellRowSpan);
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);
// }
if (element instanceof JRPrintText)
{
exportText(tableBuilder, (JRPrintText)element, gridCell);
}
// else if (element instanceof JRPrintFrame)
// {
// //exportFrame(tableBuilder, (JRPrintFrame)element, gridCell);
// }
colIndex += gridCell.getColSpan() - 1;
}
else
{
emptyCellColSpan++;
emptyCellWidth += gridCell.getWidth();
}
}
if (emptyCellColSpan > 0)
{
tableBuilder.buildEmptyCell(emptyCellColSpan, emptyCellRowSpan);
emptyCellColSpan = 0;
emptyCellWidth = 0;
}
tableBuilder.buildRowFooter();
//increment row index to return proper value
++rowIndex;
}
else
{
skippedRows++;
}
}
// if (createXCuts && isRemoveEmptySpaceBetweenColumns)
// {
// //FIXME: to remove empty columns when isRemoveEmptySpaceBetweenColumns
//// removeEmptyColumns(xCuts);
// }
if (progressMonitor != null)
{
progressMonitor.afterPageExport();
}
// Return the number of rows added
return rowIndex;
}
catch (IOException e)
{
throw new JRException(e);
}
}
/**
*
*/
protected void exportText(XmlssTableBuilder tableBuilder, JRPrintText text, JRExporterGridCell gridCell) throws IOException
{
JRStyledText styledText = getStyledText(text);
String pattern = getConvertedPattern(getTextValue(text,styledText.getText()));
int colspan = gridCell.getColSpan(), rowspan = gridCell.getRowSpan();
String formula = text.getPropertiesMap().getProperty(JRAbstractExporter.PROPERTY_CELL_FORMULA);
//FIXME: transfer the font properties to the cell style
tableBuilder.buildCellHeader(styleCache.getCellStyle(text, gridCell.getBackcolor(), pattern, isFontSizeFixEnabled, defaultFont, fontMap),
colspan,
rowspan,
getHyperlinkURL(text),
text.getHyperlinkTooltip(),
formula
);
int textLength = 0;
if (styledText != null)
{
textLength = styledText.length();
}
tempBodyWriter.write(" <ss:Data ss:Type=\""+getType(getTextValue(text,styledText.getText()))+"\" xmlns=\"http://www.w3.org/TR/REC-html40\">");
//FIXME: when the font properties will be transfered to the cell style, uncomment this
// if(JRCommonText.MARKUP_NONE.equals(text.getMarkup()))
// {
// tempBodyWriter.write((JRStringUtil.xmlEncode(styledText.getText())).replaceAll("\n", "
"));
// }
// else if (textLength > 0)
if (textLength > 0)
{
exportStyledText(styledText);
}
tempBodyWriter.write(" </ss:Data>\n");
tableBuilder.buildCellFooter();
}
/**
*
*/
protected void exportStyledText(JRStyledText styledText) throws IOException
{
String text = styledText.getText();
int runLimit = 0;
AttributedCharacterIterator iterator = styledText.getAttributedString().getIterator();
while(runLimit < styledText.length() && (runLimit = iterator.getRunLimit()) <= styledText.length())
{
exportStyledTextRun(iterator.getAttributes(), text.substring(iterator.getIndex(), runLimit));
iterator.setIndex(runLimit);
}
}
/**
*
*/
protected void exportStyledTextRun(Map attributes, String text) throws IOException
{
boolean hasFont = false;
boolean isBold = false;
boolean isItalic = false;
boolean isStrikethrough = false;
boolean isUnderline = false;
boolean isSubscript = false;
boolean isSuperscript = false;
if (TextAttribute.WEIGHT_BOLD.equals(attributes.get(TextAttribute.WEIGHT)))
{
isBold = true;
tempBodyWriter.write("<B>");
}
if (TextAttribute.POSTURE_OBLIQUE.equals(attributes.get(TextAttribute.POSTURE)))
{
isItalic = true;
tempBodyWriter.write("<I>");
}
if (TextAttribute.UNDERLINE_ON.equals(attributes.get(TextAttribute.UNDERLINE)))
{
isUnderline = true;
tempBodyWriter.write("<U>");
}
if (TextAttribute.STRIKETHROUGH_ON.equals(attributes.get(TextAttribute.STRIKETHROUGH)))
{
isStrikethrough = true;
tempBodyWriter.write("<S>");
}
if (TextAttribute.SUPERSCRIPT_SUPER.equals(attributes.get(TextAttribute.SUPERSCRIPT)))
{
isSuperscript = true;
tempBodyWriter.write("<Sup>");
}
else if (TextAttribute.SUPERSCRIPT_SUB.equals(attributes.get(TextAttribute.SUPERSCRIPT)))
{
isSubscript = true;
tempBodyWriter.write("<Sub>");
}
// String fontFamilyAttr = (String)attributes.get(TextAttribute.FAMILY);
// String fontFamily = (fontMap != null && fontMap.containsKey(fontFamilyAttr))
// ? (String) fontMap.get(fontFamilyAttr)
// : fontFamilyAttr;
//
// if(fontFamily != null)
// {
// hasFont = true;
// startFontTag();
// tempBodyWriter.write(" x:Family=\"" + fontFamily+"\"");
// }
Font font = (Font)attributes.get(TextAttribute.FONT);
if(font != null)
{
String fontFace = font.getFontName();
if(fontFace != null)
{
if(!hasFont)
{
hasFont = true;
startFontTag();
}
tempBodyWriter.write(" html:Face=\"" + fontFace +"\"");
}
int size = font.getSize();
if(size > 0)
{
if(!hasFont)
{
hasFont = true;
startFontTag();
}
tempBodyWriter.write(" html:Size=\"" + size +"\"");
}
}
else
{
//FIXMEXMLSS: how to distinguish between font name and font family;
// now it's possible thanks to FONT_NAME attribute;
// see other exporters for details about font mapping
String fontFamilyAttr = (String)attributes.get(TextAttribute.FAMILY);
String fontFamily = (fontMap != null && fontMap.containsKey(fontFamilyAttr))
? (String) fontMap.get(fontFamilyAttr)
: fontFamilyAttr;
if(fontFamily != null)
{
if(!hasFont)
{
hasFont = true;
startFontTag();
}
tempBodyWriter.write(" html:Face=\"" + fontFamily +"\"");
}
Number size = (Number)attributes.get(TextAttribute.SIZE);
if(size != null)
{
if(! hasFont)
{
hasFont = true;
startFontTag();
}
tempBodyWriter.write(" html:Size=\"" + size +"\"");
}
}
Color forecolor = (Color)attributes.get(TextAttribute.FOREGROUND);
if(forecolor != null && !forecolor.equals(Color.BLACK))
{
if(!hasFont)
{
hasFont =true;
startFontTag();
}
tempBodyWriter.write(" html:Color=\"#" + JRColorUtil.getColorHexa(forecolor)+"\"");
}
if(hasFont)
{
tempBodyWriter.write(">");
}
if (text != null)
{
tempBodyWriter.write((JRStringUtil.xmlEncode(text)).replaceAll("\n", "
"));
}
if(hasFont)
{
tempBodyWriter.write("</Font>");
}
if(isSubscript)
{
tempBodyWriter.write("</Sub>");
}
if(isSuperscript)
{
tempBodyWriter.write("</Sup>");
}
if(isStrikethrough)
{
tempBodyWriter.write("</S>");
}
if(isUnderline)
{
tempBodyWriter.write("</U>");
}
if(isItalic)
{
tempBodyWriter.write("</I>");
}
if(isBold)
{
tempBodyWriter.write("</B>");
}
}
/**
*
*/
protected JRPrintElementIndex getElementIndex(JRExporterGridCell gridCell)
{
JRPrintElementIndex imageIndex =
new JRPrintElementIndex(
reportIndex,
pageIndex,
gridCell.getWrapper().getAddress()
);
return imageIndex;
}
/**
*
*/
public static JRPrintElementIndex getPrintElementIndex(String imageName)
{
if (!imageName.startsWith(IMAGE_NAME_PREFIX))
{
throw new JRRuntimeException("Invalid image name: " + imageName);
}
return JRPrintElementIndex.parsePrintElementIndex(imageName.substring(IMAGE_NAME_PREFIX_LEGTH));
}
/**
*
*/
protected void exportFrame(XmlssTableBuilder tableBuilder, JRPrintFrame frame, JRExporterGridCell gridCell) throws IOException
{
tableBuilder.buildCellHeader(styleCache.getCellStyle(frame, gridCell.getBackcolor(), null, isFontSizeFixEnabled, defaultFont, fontMap), gridCell.getColSpan(), gridCell.getRowSpan(), null, null, null);
// boolean appendBackcolor =
// frame.getModeValue() == ModeEnum.OPAQUE
// && (backcolor == null || frame.getBackcolor().getRGB() != backcolor.getRGB());
//
// if (appendBackcolor)
// {
// setBackcolor(frame.getBackcolor());
// }
// try
// {
//// JRGridLayout layout = gridCell.getLayout();
//// JRPrintElementIndex frameIndex =
//// new JRPrintElementIndex(
//// reportIndex,
//// pageIndex,
//// gridCell.getWrapper().getAddress()
//// );
// //FIXME: make it functional
//// exportPage(layout, frameIndex);
// }
// finally
// {
// if (appendBackcolor)
// {
// restoreBackcolor();
// }
// }
tableBuilder.buildCellFooter();
}
/**
*
*/
protected void setBackcolor(Color color)
{
backcolorStack.addLast(backcolor);
backcolor = color;
}
protected void restoreBackcolor()
{
backcolor = (Color) backcolorStack.removeLast();
}
protected void writeHyperlink(JRPrintHyperlink link) throws IOException
{
String href = getHyperlinkURL(link);
if(link != null)
{
tempBodyWriter.write(" ss:Href=\"");
tempBodyWriter.write(href);
tempBodyWriter.write("\"");
if (link.getHyperlinkTooltip() != null)
{
tempBodyWriter.write(" x:HRefScreenTip=\"");
tempBodyWriter.write(JRStringUtil.xmlEncode(link.getHyperlinkTooltip()));
tempBodyWriter.write("\"");
}
tempBodyWriter.write(">");
}
}
protected String getHyperlinkURL(JRPrintHyperlink link)
{
//FIXME: find the appropriate way to write the local anchor and local page hyperlinks
String href = null;
JRHyperlinkProducer customHandler = getCustomHandler(link);
if (customHandler == null)
{
switch(link.getHyperlinkTypeValue())
{
case REFERENCE :
{
if (link.getHyperlinkReference() != null)
{
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 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
);
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
);
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
);
sheetNames = (String[])parameters.get(JRXlsAbstractExporterParameter.SHEET_NAMES);
fontMap = (Map) parameters.get(JRExporterParameter.FONT_MAP);
formatPatternsMap = (Map)getParameter(JRXlsExporterParameter.FORMAT_PATTERNS_MAP);
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
);
encoding =
getStringParameterOrDefault(
JRExporterParameter.CHARACTER_ENCODING,
JRExporterParameter.PROPERTY_CHARACTER_ENCODING
);
setHyperlinkProducerFactory();
}
protected void startFontTag() throws IOException
{
tempBodyWriter.write("<Font");
}
protected void endFontTag() throws IOException
{
tempBodyWriter.write("</Font>");
}
/**
*
*/
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;
}
int currentIndex = ((Integer)sheetNamesMap.get(sheetName)).intValue() + 1;
sheetNamesMap.put(sheetName, Integer.valueOf(currentIndex));
return sheetName + " " + currentIndex;
}
protected void buildColumns(CutsInfo xCuts, XmlssTableBuilder tableBuilder)
{
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);
try {
tableBuilder.buildColumnTag(col+1, width);
} catch (IOException e) {
throw new JRRuntimeException(e);
}
}
}
}
String getType(TextValue textValue)
{
String type = "String";
if(textValue instanceof NumberTextValue)
{
type = "Number";
}
else if(textValue instanceof DateTextValue)
{
type = "DateTime";
}
else if(textValue instanceof BooleanTextValue)
{
type = "Boolean";
}
return type;
}
/**
* This method is intended to modify a given format pattern so to include
* only the accepted proprietary format characters. The resulted pattern
* will possibly truncate the original pattern
* @param pattern
* @return pattern converted to accepted proprietary formats
*/
String getConvertedPattern(TextValue textValue)
{
String pattern = "General";
if(textValue instanceof NumberTextValue && ((NumberTextValue)textValue).getPattern() != null)
{
pattern = ((NumberTextValue)textValue).getPattern();
}
else if(textValue instanceof DateTextValue && ((DateTextValue)textValue).getPattern() != null)
{
pattern = ((DateTextValue)textValue).getPattern();
}
if (formatPatternsMap != null && formatPatternsMap.containsKey(pattern))
{
return (String) formatPatternsMap.get(pattern);
}
return pattern;
}
private void closeWorksheet() throws IOException
{
tempBodyWriter.write("<x:WorksheetOptions>\n");
tempBodyWriter.write(" <x:PageSetup>\n");
tempBodyWriter.write(" <x:Layout x:Orientation=\"" +PAGE_LAYOUT[pageOrientation.getValue()]+"\"/>\n");
tempBodyWriter.write(" </x:PageSetup>\n");
tempBodyWriter.write("</x:WorksheetOptions>\n");
tempBodyWriter.write("</Worksheet>\n");
}
/**
*
*/
protected String getExporterKey()
{
return XMLSS_EXPORTER_KEY;
}
}