net.sf.jasperreports.engine.export.JRRtfExporter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jasperreports Show documentation
Show all versions of jasperreports Show documentation
Free Java Reporting Library
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2019 TIBCO Software Inc. All rights reserved.
* http://www.jaspersoft.com
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is part of JasperReports.
*
* JasperReports is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JasperReports is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JasperReports. If not, see .
*/
/*
* Contributors:
* Matt Thompson - [email protected]
*/
package net.sf.jasperreports.engine.export;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.font.TextAttribute;
import java.awt.geom.Dimension2D;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.text.AttributedCharacterIterator;
import java.text.AttributedCharacterIterator.Attribute;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import net.sf.jasperreports.engine.DefaultJasperReportsContext;
import net.sf.jasperreports.engine.JRAbstractExporter;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRFont;
import net.sf.jasperreports.engine.JRGenericElementType;
import net.sf.jasperreports.engine.JRGenericPrintElement;
import net.sf.jasperreports.engine.JRLineBox;
import net.sf.jasperreports.engine.JRPen;
import net.sf.jasperreports.engine.JRPrintElement;
import net.sf.jasperreports.engine.JRPrintEllipse;
import net.sf.jasperreports.engine.JRPrintFrame;
import net.sf.jasperreports.engine.JRPrintHyperlink;
import net.sf.jasperreports.engine.JRPrintImage;
import net.sf.jasperreports.engine.JRPrintLine;
import net.sf.jasperreports.engine.JRPrintPage;
import net.sf.jasperreports.engine.JRPrintRectangle;
import net.sf.jasperreports.engine.JRPrintText;
import net.sf.jasperreports.engine.JRPropertiesUtil;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.TabStop;
import net.sf.jasperreports.engine.base.JRBaseFont;
import net.sf.jasperreports.engine.base.JRBasePrintText;
import net.sf.jasperreports.engine.type.ImageTypeEnum;
import net.sf.jasperreports.engine.type.LineDirectionEnum;
import net.sf.jasperreports.engine.type.ModeEnum;
import net.sf.jasperreports.engine.type.OrientationEnum;
import net.sf.jasperreports.engine.type.RotationEnum;
import net.sf.jasperreports.engine.type.RunDirectionEnum;
import net.sf.jasperreports.engine.type.ScaleImageEnum;
import net.sf.jasperreports.engine.util.FileBufferedWriter;
import net.sf.jasperreports.engine.util.ImageUtil;
import net.sf.jasperreports.engine.util.JRStyledText;
import net.sf.jasperreports.engine.util.JRTypeSniffer;
import net.sf.jasperreports.export.ExportInterruptedException;
import net.sf.jasperreports.export.ExporterInputItem;
import net.sf.jasperreports.export.RtfExporterConfiguration;
import net.sf.jasperreports.export.RtfReportConfiguration;
import net.sf.jasperreports.export.WriterExporterOutput;
import net.sf.jasperreports.renderers.DataRenderable;
import net.sf.jasperreports.renderers.DimensionRenderable;
import net.sf.jasperreports.renderers.Renderable;
import net.sf.jasperreports.renderers.RenderersCache;
import net.sf.jasperreports.renderers.ResourceRenderer;
/**
* Exports a JasperReports document to RTF format.
*
* The {@link net.sf.jasperreports.engine.export.JRRtfExporter} implementation helps
* to export JasperPrint documents in RTF format using RTF Specification 1.6. This
* means that the RTF files produced by this exporter are compatible with Microsoft Word
* 6.0, 2003 and XP.
*
* However, users might experience some problems when opening those RTF files with
* OpenOffice or StarOffice, as these products are not perfectly compatible with the RTF
* specifications from Microsoft.
*
* RTF is a character-based file format that supports absolute positioning of elements,
* which means that this exporter produces output very similar to that of the Graphics2D
* and PDF exporters. The {@link net.sf.jasperreports.export.RtfReportConfiguration} provides special
* configuration settings for this exporter.
*
* Almost all the provided samples show how to export to RTF.
*
* @see net.sf.jasperreports.export.RtfReportConfiguration
* @author Flavius Sana ([email protected])
*/
public class JRRtfExporter extends JRAbstractExporter
{
private static final Log log = LogFactory.getLog(JRRtfExporter.class);
public static final String RTF_EXPORTER_PROPERTIES_PREFIX = JRPropertiesUtil.PROPERTY_PREFIX + "export.rtf.";
public static final String EXCEPTION_MESSAGE_KEY_INVALID_TEXT_HEIGHT = "export.rtf.invalid.text.height";
private static final int LINE_SPACING_FACTOR = 240; //(int)(240 * 2/3f);
/**
* The exporter key, as used in
* {@link GenericElementHandlerEnviroment#getElementHandler(JRGenericElementType, String)}.
*/
public static final String RTF_EXPORTER_KEY = JRPropertiesUtil.PROPERTY_PREFIX + "rtf";
/**
*
*/
protected static final String JR_PAGE_ANCHOR_PREFIX = "JR_PAGE_ANCHOR_";
protected FileBufferedWriter colorWriter;
protected FileBufferedWriter fontWriter;
protected FileBufferedWriter contentWriter;
protected File destFile;
protected int reportIndex;
protected List colors;
protected List fonts;
// z order of the graphical objects in .rtf file
private int zorder = 1;
protected RenderersCache renderersCache;
protected class ExporterContext extends BaseExporterContext implements JRRtfExporterContext
{
}
/**
* @see #JRRtfExporter(JasperReportsContext)
*/
public JRRtfExporter()
{
this(DefaultJasperReportsContext.getInstance());
}
/**
*
*/
public JRRtfExporter(JasperReportsContext jasperReportsContext)
{
super(jasperReportsContext);
exporterContext = new ExporterContext();
}
@Override
protected Class getConfigurationInterface()
{
return RtfExporterConfiguration.class;
}
@Override
protected Class getItemConfigurationInterface()
{
return RtfReportConfiguration.class;
}
@Override
@SuppressWarnings("deprecation")
protected void ensureOutput()
{
if (exporterOutput == null)
{
exporterOutput =
new net.sf.jasperreports.export.parameters.ParametersWriterExporterOutput(
getJasperReportsContext(),
getParameters(),
getCurrentJasperPrint()
);
}
}
@Override
public void exportReport() throws JRException
{
/* */
ensureJasperReportsContext();
ensureInput();
fonts = new ArrayList();
colors = new ArrayList();
colors.add(null);
initExport();
ensureOutput();
Writer writer = getExporterOutput().getWriter();
try
{
exportReportToWriter(writer);
}
catch (IOException e)
{
throw
new JRException(
EXCEPTION_MESSAGE_KEY_OUTPUT_WRITER_ERROR,
new Object[]{jasperPrint.getName()},
e);
}
finally
{
getExporterOutput().close();
resetExportContext();
}
}
@Override
protected void initExport()
{
super.initExport();
}
@Override
protected void initReport()
{
super.initReport();
renderersCache = new RenderersCache(getJasperReportsContext());
}
/**
* Export report in .rtf format to a stream
* @throws JRException
* @throws IOException
*/
protected void exportReportToWriter(Writer writer) throws JRException, IOException
{
colorWriter = new FileBufferedWriter();
fontWriter = new FileBufferedWriter();
contentWriter = new FileBufferedWriter();
List items = exporterInput.getItems();
for (reportIndex = 0; reportIndex < items.size(); reportIndex++ )
{
ExporterInputItem item = items.get(reportIndex);
setCurrentExporterInputItem(item);
List pages = jasperPrint.getPages();
if (pages != null && pages.size() > 0)
{
PageRange pageRange = getPageRange();
int startPageIndex = (pageRange == null || pageRange.getStartPageIndex() == null) ? 0 : pageRange.getStartPageIndex();
int endPageIndex = (pageRange == null || pageRange.getEndPageIndex() == null) ? (pages.size() - 1) : pageRange.getEndPageIndex();
contentWriter.write("{\\info{\\nofpages");
contentWriter.write(String.valueOf(pages.size()));
contentWriter.write("}}\n");
contentWriter.write("\\viewkind1\\paperw");
contentWriter.write(String.valueOf(LengthUtil.twip(jasperPrint.getPageWidth())));//FIXMEPART rtf does not work in batch mode
contentWriter.write("\\paperh");
contentWriter.write(String.valueOf(LengthUtil.twip(jasperPrint.getPageHeight())));
contentWriter.write("\\marglsxn");
contentWriter.write(String.valueOf(LengthUtil.twip(jasperPrint.getLeftMargin() == null ? 0 : jasperPrint.getLeftMargin())));
contentWriter.write("\\margrsxn");
contentWriter.write(String.valueOf(LengthUtil.twip(jasperPrint.getRightMargin() == null ? 0 : jasperPrint.getRightMargin())));
contentWriter.write("\\margtsxn");
contentWriter.write(String.valueOf(LengthUtil.twip(jasperPrint.getTopMargin() == null ? 0 : jasperPrint.getTopMargin())));
contentWriter.write("\\margbsxn");
contentWriter.write(String.valueOf(LengthUtil.twip(jasperPrint.getBottomMargin() == null ? 0 : jasperPrint.getBottomMargin())));
contentWriter.write("\\deftab");
contentWriter.write(String.valueOf(LengthUtil.twip(new JRBasePrintText(jasperPrint.getDefaultStyleProvider()).getParagraph().getTabStopWidth())));
if (jasperPrint.getOrientationValue() == OrientationEnum.LANDSCAPE) {
contentWriter.write("\\lndscpsxn");
}
for (int pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++)
{
if (Thread.interrupted())
{
throw
new ExportInterruptedException();
}
JRPrintPage page = pages.get(pageIndex);
contentWriter.write("\n");
writeAnchor(JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + (pageIndex + 1));
boolean lastPageFlag = false;
if(pageIndex == endPageIndex && reportIndex == (items.size() - 1)){
lastPageFlag = true;
}
exportPage(page, lastPageFlag);
}
}
}
contentWriter.write("}\n");
contentWriter.close();
colorWriter.close();
fontWriter.close();
// create the header of the rtf file
writer.write("{\\rtf1\\ansi\\deff0\n");
// create font and color tables
writer.write("{\\fonttbl ");
fontWriter.writeData(writer);
writer.write("}\n");
writer.write("{\\colortbl ;");
colorWriter.writeData(writer);
writer.write("}\n");
contentWriter.writeData(writer);
writer.flush();
contentWriter.dispose();
colorWriter.dispose();
fontWriter.dispose();
}
/**
* Return color index from header of the .rtf file. If a color is not
* found is automatically added to the header of the rtf file. The
* method is called first when the header of the .rtf file is constructed
* and when a component needs a color for foreground or background
* @param color Color for which the index is required.
* @return index of the color from .rtf file header
*/
private int getColorIndex(Color color) throws IOException
{
int colorNdx = colors.indexOf(color);
if (colorNdx < 0)
{
colorNdx = colors.size();
colors.add(color);
colorWriter.write(
"\\red" + color.getRed()
+ "\\green" + color.getGreen()
+ "\\blue" + color.getBlue() + ";"
);
}
return colorNdx;
}
/**
* Return font index from the header of the .rtf file. The method is
* called first when the header of the .rtf document is constructed and when a
* text component needs font informations.
* @param font the font for which the index is required
* @return index of the font from .rtf file header
*/
private int getFontIndex(JRFont font, Locale locale) throws IOException
{
String fontName = fontUtil.getExportFontFamily(font.getFontName(), locale, getExporterKey());
int fontIndex = fonts.indexOf(fontName);
if(fontIndex < 0) {
fontIndex = fonts.size();
fonts.add(fontName);
fontWriter.write("{\\f" + fontIndex + "\\fnil " + fontName + ";}");
}
return fontIndex;
}
/**
* Exports a report page
* @param page Page that will be exported
* @throws JRException
*/
protected void exportPage(JRPrintPage page, boolean lastPage) throws JRException, IOException
{
exportElements(page.getElements());
if(!lastPage)
{
contentWriter.write("\\page\n");
}
JRExportProgressMonitor progressMonitor = getCurrentItemConfiguration().getProgressMonitor();
if (progressMonitor != null)
{
progressMonitor.afterPageExport();
}
}
/**
*
*/
private void startElement(JRPrintElement element) throws IOException
{
contentWriter.write("{\\shp\\shpbxpage\\shpbypage\\shpwr5\\shpfhdr0\\shpfblwtxt0\\shpz");
contentWriter.write(String.valueOf(zorder++));
contentWriter.write("\\shpleft");
contentWriter.write(String.valueOf(LengthUtil.twip(element.getX() + getOffsetX())));
contentWriter.write("\\shpright");
contentWriter.write(String.valueOf(LengthUtil.twip(element.getX() + getOffsetX() + element.getWidth())));
contentWriter.write("\\shptop");
contentWriter.write(String.valueOf(LengthUtil.twip(element.getY() + getOffsetY())));
contentWriter.write("\\shpbottom");
contentWriter.write(String.valueOf(LengthUtil.twip(element.getY() + getOffsetY() + element.getHeight())));
Color bgcolor = element.getBackcolor();
if (element.getModeValue() == ModeEnum.OPAQUE)
{
contentWriter.write("{\\sp{\\sn fFilled}{\\sv 1}}");
contentWriter.write("{\\sp{\\sn fillColor}{\\sv ");
contentWriter.write(String.valueOf(getColorRGB(bgcolor)));
contentWriter.write("}}");
}
else
{
contentWriter.write("{\\sp{\\sn fFilled}{\\sv 0}}");
}
contentWriter.write("{\\shpinst");
}
/**
*
*/
private int getColorRGB(Color color)
{
return color.getRed() + 256 * color.getGreen() + 65536 * color.getBlue();
}
/**
*
*/
private void finishElement() throws IOException
{
contentWriter.write("}}\n");
}
/**
*
*/
private void exportPen(JRPen pen) throws IOException
{
contentWriter.write("{\\sp{\\sn lineColor}{\\sv ");
contentWriter.write(String.valueOf(getColorRGB(pen.getLineColor())));
contentWriter.write("}}");
float lineWidth = pen.getLineWidth();
if (lineWidth == 0f)
{
contentWriter.write("{\\sp{\\sn fLine}{\\sv 0}}");
}
switch (pen.getLineStyleValue())
{
case DOUBLE :
{
contentWriter.write("{\\sp{\\sn lineStyle}{\\sv 1}}");
break;
}
case DOTTED :
{
contentWriter.write("{\\sp{\\sn lineDashing}{\\sv 2}}");
break;
}
case DASHED :
{
contentWriter.write("{\\sp{\\sn lineDashing}{\\sv 1}}");
break;
}
}
contentWriter.write("{\\sp{\\sn lineWidth}{\\sv ");
contentWriter.write(String.valueOf(LengthUtil.emu(lineWidth)));
contentWriter.write("}}");
}
/**
*
*/
private void exportPen(Color color) throws IOException
{
contentWriter.write("{\\sp{\\sn lineColor}{\\sv ");
contentWriter.write(String.valueOf(getColorRGB(color)));
contentWriter.write("}}");
contentWriter.write("{\\sp{\\sn fLine}{\\sv 0}}");
contentWriter.write("{\\sp{\\sn lineWidth}{\\sv 0}}");
}
/**
* Draw a line object
* @param line JasperReports line object - JRPrintLine
* @throws IOException
*/
protected void exportLine(JRPrintLine line) throws IOException
{
int x = line.getX() + getOffsetX();
int y = line.getY() + getOffsetY();
int height = line.getHeight();
int width = line.getWidth();
if (width <= 1 || height <= 1)
{
if (width > 1)
{
height = 0;
}
else
{
width = 0;
}
}
contentWriter.write("{\\shp\\shpbxpage\\shpbypage\\shpwr5\\shpfhdr0\\shpz");
contentWriter.write(String.valueOf(zorder++));
contentWriter.write("\\shpleft");
contentWriter.write(String.valueOf(LengthUtil.twip(x)));
contentWriter.write("\\shpright");
contentWriter.write(String.valueOf(LengthUtil.twip(x + width)));
contentWriter.write("\\shptop");
contentWriter.write(String.valueOf(LengthUtil.twip(y)));
contentWriter.write("\\shpbottom");
contentWriter.write(String.valueOf(LengthUtil.twip(y + height)));
contentWriter.write("{\\shpinst");
contentWriter.write("{\\sp{\\sn shapeType}{\\sv 20}}");
exportPen(line.getLinePen());
if (line.getDirectionValue() == LineDirectionEnum.TOP_DOWN)
{
contentWriter.write("{\\sp{\\sn fFlipV}{\\sv 0}}");
}
else
{
contentWriter.write("{\\sp{\\sn fFlipV}{\\sv 1}}");
}
contentWriter.write("}}\n");
}
/**
*
*/
private void exportBorder(JRPen pen, float x, float y, float width, float height) throws IOException
{
contentWriter.write("{\\shp\\shpbxpage\\shpbypage\\shpwr5\\shpfhdr0\\shpz");
contentWriter.write(String.valueOf(zorder++));
contentWriter.write("\\shpleft");
contentWriter.write(String.valueOf(LengthUtil.twip(x)));//FIXMEBORDER starting point of borders seem to have CAP_SQUARE-like appearence at least for Thin
contentWriter.write("\\shpright");
contentWriter.write(String.valueOf(LengthUtil.twip(x + width)));
contentWriter.write("\\shptop");
contentWriter.write(String.valueOf(LengthUtil.twip(y)));
contentWriter.write("\\shpbottom");
contentWriter.write(String.valueOf(LengthUtil.twip(y + height)));
contentWriter.write("{\\shpinst");
contentWriter.write("{\\sp{\\sn shapeType}{\\sv 20}}");
exportPen(pen);
contentWriter.write("}}\n");
}
/**
* Draw a rectangle
* @param rectangle JasperReports rectangle object (JRPrintRectangle)
*/
protected void exportRectangle(JRPrintRectangle rectangle) throws IOException
{
startElement(rectangle);
if (rectangle.getRadius() == 0)
{
contentWriter.write("{\\sp{\\sn shapeType}{\\sv 1}}");
}
else
{
contentWriter.write("{\\sp{\\sn shapeType}{\\sv 2}}");
}
exportPen(rectangle.getLinePen());
finishElement();
}
/**
* Draw a ellipse object
* @param ellipse JasperReports ellipse object (JRPrintElipse)
*/
protected void exportEllipse(JRPrintEllipse ellipse) throws IOException
{
startElement(ellipse);
contentWriter.write("{\\sp{\\sn shapeType}{\\sv 3}}");
exportPen(ellipse.getLinePen());
finishElement();
}
/**
* Draw a text box
* @param text JasperReports text object (JRPrintText)
* @throws JRException
*/
public void exportText(JRPrintText text) throws IOException, JRException {
// use styled text
JRStyledText styledText = getStyledText(text);
if (styledText == null)
{
return;
}
int width = text.getWidth();
int height = text.getHeight();
int textHeight = (int)text.getTextHeight();
if(textHeight <= 0) {
if(height <= 0 ){
throw
new JRException(
EXCEPTION_MESSAGE_KEY_INVALID_TEXT_HEIGHT,
(Object[])null
);
}
textHeight = height;
}
/* */
startElement(text);
// padding for the text
int topPadding = text.getLineBox().getTopPadding();
int leftPadding = text.getLineBox().getLeftPadding();
int bottomPadding = text.getLineBox().getBottomPadding();
int rightPadding = text.getLineBox().getRightPadding();
String rotation = null;
switch (text.getRotationValue())
{
case LEFT :
{
switch (text.getVerticalTextAlign())
{
case BOTTOM:
{
leftPadding = Math.max(leftPadding, width - rightPadding - textHeight);
break;
}
case MIDDLE:
{
leftPadding = Math.max(leftPadding, (width - rightPadding - textHeight) / 2);
break;
}
case TOP:
case JUSTIFIED:
default:
{
}
}
rotation = "{\\sp{\\sn txflTextFlow}{\\sv 2}}";
break;
}
case RIGHT :
{
switch (text.getVerticalTextAlign())
{
case BOTTOM:
{
rightPadding = Math.max(rightPadding, width - leftPadding - textHeight);
break;
}
case MIDDLE:
{
rightPadding = Math.max(rightPadding, (width - leftPadding - textHeight) / 2);
break;
}
case TOP:
case JUSTIFIED:
default:
{
}
}
rotation = "{\\sp{\\sn txflTextFlow}{\\sv 3}}";
break;
}
case UPSIDE_DOWN :
{
switch (text.getVerticalTextAlign())
{
case TOP:
{
topPadding = Math.max(topPadding, height - bottomPadding - textHeight);
break;
}
case MIDDLE:
{
topPadding = Math.max(topPadding, (height - bottomPadding - textHeight) / 2);
break;
}
case BOTTOM:
case JUSTIFIED:
default:
{
}
}
rotation = "";
break;
}
case NONE :
default :
{
switch (text.getVerticalTextAlign())
{
case BOTTOM:
{
topPadding = Math.max(topPadding, height - bottomPadding - textHeight);
break;
}
case MIDDLE:
{
topPadding = Math.max(topPadding, (height - bottomPadding - textHeight) / 2);
break;
}
case TOP:
case JUSTIFIED:
default:
{
}
}
rotation = "";
}
}
contentWriter.write(rotation);
contentWriter.write("{\\sp{\\sn dyTextTop}{\\sv ");
contentWriter.write(String.valueOf(LengthUtil.emu(topPadding)));
contentWriter.write("}}");
contentWriter.write("{\\sp{\\sn dxTextLeft}{\\sv ");
contentWriter.write(String.valueOf(LengthUtil.emu(leftPadding)));
contentWriter.write("}}");
contentWriter.write("{\\sp{\\sn dyTextBottom}{\\sv ");
contentWriter.write(String.valueOf(LengthUtil.emu(bottomPadding)));
contentWriter.write("}}");
contentWriter.write("{\\sp{\\sn dxTextRight}{\\sv ");
contentWriter.write(String.valueOf(LengthUtil.emu(rightPadding)));
contentWriter.write("}}");
contentWriter.write("{\\sp{\\sn fLine}{\\sv 0}}");
contentWriter.write("{\\shptxt{\\pard ");
contentWriter.write("\\fi" + LengthUtil.twip(text.getParagraph().getFirstLineIndent()) + " ");
contentWriter.write("\\li" + LengthUtil.twip(text.getParagraph().getLeftIndent()) + " ");
contentWriter.write("\\ri" + LengthUtil.twip(text.getParagraph().getRightIndent()) + " ");
contentWriter.write("\\sb" + LengthUtil.twip(text.getParagraph().getSpacingBefore()) + " ");
contentWriter.write("\\sa" + LengthUtil.twip(text.getParagraph().getSpacingAfter()) + " ");
TabStop[] tabStops = text.getParagraph().getTabStops();
if (tabStops != null && tabStops.length > 0)
{
for (int i = 0; i < tabStops.length; i++)
{
TabStop tabStop = tabStops[i];
String tabStopAlign = "";
switch (tabStop.getAlignment())
{
case CENTER:
tabStopAlign = "\\tqc";
break;
case RIGHT:
tabStopAlign = "\\tqr";
break;
case LEFT:
default:
tabStopAlign = "";
break;
}
contentWriter.write(tabStopAlign + "\\tx" + LengthUtil.twip(tabStop.getPosition()) + " ");
}
}
// JRFont font = text;
if (text.getRunDirectionValue() == RunDirectionEnum.RTL)
{
contentWriter.write("\\rtlch");
}
// writer.write("\\f");
// writer.write(String.valueOf(getFontIndex(font)));
// writer.write("\\cf");
// writer.write(String.valueOf(getColorIndex(text.getForecolor())));
contentWriter.write("\\cb");
contentWriter.write(String.valueOf(getColorIndex(text.getBackcolor())));
contentWriter.write(" ");
// if (font.isBold())
// writer.write("\\b");
// if (font.isItalic())
// writer.write("\\i");
// if (font.isStrikeThrough())
// writer.write("\\strike");
// if (font.isUnderline())
// writer.write("\\ul");
// writer.write("\\fs");
// writer.write(String.valueOf(font.getFontSize() * 2));
switch (text.getHorizontalTextAlign())
{
case LEFT:
contentWriter.write("\\ql");
break;
case CENTER:
contentWriter.write("\\qc");
break;
case RIGHT:
contentWriter.write("\\qr");
break;
case JUSTIFIED:
contentWriter.write("\\qj");
break;
default:
contentWriter.write("\\ql");
break;
}
switch (text.getParagraph().getLineSpacing())
{
case AT_LEAST:
{
contentWriter.write("\\sl" + LengthUtil.twip(text.getParagraph().getLineSpacingSize()));
contentWriter.write(" \\slmult0 ");
break;
}
case FIXED:
{
contentWriter.write("\\sl-" + LengthUtil.twip(text.getParagraph().getLineSpacingSize()));
contentWriter.write(" \\slmult0 ");
break;
}
case PROPORTIONAL:
{
contentWriter.write("\\sl" + (int)(text.getParagraph().getLineSpacingSize() * LINE_SPACING_FACTOR));
contentWriter.write(" \\slmult1 ");
break;
}
case DOUBLE:
{
contentWriter.write("\\sl" + (int)(2f * LINE_SPACING_FACTOR));
contentWriter.write(" \\slmult1 ");
break;
}
case ONE_AND_HALF:
{
contentWriter.write("\\sl" + (int)(1.5f * LINE_SPACING_FACTOR));
contentWriter.write(" \\slmult1 ");
break;
}
case SINGLE:
default:
{
contentWriter.write("\\sl" + (int)(1f * LINE_SPACING_FACTOR));
contentWriter.write(" \\slmult1 ");
break;
}
}
if (text.getAnchorName() != null)
{
writeAnchor(text.getAnchorName());
}
boolean startedHyperlink = exportHyperlink(text);
// add parameters in case of styled text element
String plainText = styledText.getText();
int runLimit = 0;
AttributedCharacterIterator iterator = styledText.getAttributedString().getIterator();
while (
runLimit < styledText.length()
&& (runLimit = iterator.getRunLimit()) <= styledText.length()
)
{
Map styledTextAttributes = iterator.getAttributes();
JRFont styleFont = new JRBaseFont(styledTextAttributes);
Color styleForeground = (Color) styledTextAttributes.get(TextAttribute.FOREGROUND);
Color styleBackground = (Color) styledTextAttributes.get(TextAttribute.BACKGROUND);
contentWriter.write("\\f");
contentWriter.write(String.valueOf(getFontIndex(styleFont, getTextLocale(text))));
contentWriter.write("\\fs");
contentWriter.write(String.valueOf((int)(2 * styleFont.getFontsize())));
if (styleFont.isBold())
{
contentWriter.write("\\b");
}
if (styleFont.isItalic())
{
contentWriter.write("\\i");
}
if (styleFont.isUnderline())
{
contentWriter.write("\\ul");
}
if (styleFont.isStrikeThrough())
{
contentWriter.write("\\strike");
}
if (TextAttribute.SUPERSCRIPT_SUPER.equals(styledTextAttributes.get(TextAttribute.SUPERSCRIPT)))
{
contentWriter.write("\\super");
}
else if (TextAttribute.SUPERSCRIPT_SUB.equals(styledTextAttributes.get(TextAttribute.SUPERSCRIPT)))
{
contentWriter.write("\\sub");
}
if(!(null == styleBackground || styleBackground.equals(text.getBackcolor()))){
contentWriter.write("\\highlight");
contentWriter.write(String.valueOf(getColorIndex(styleBackground)));
}
contentWriter.write("\\cf");
contentWriter.write(String.valueOf(getColorIndex(styleForeground)));
contentWriter.write(" ");
contentWriter.write(
handleUnicodeText(
plainText.substring(iterator.getIndex(), runLimit)
)
);
// reset all styles in the paragraph
contentWriter.write("\\plain");
iterator.setIndex(runLimit);
}
endHyperlink(startedHyperlink);
contentWriter.write("\\par}}");
/* */
finishElement();
exportBox(text.getLineBox(), text.getX() + getOffsetX(), text.getY() + getOffsetY(), width, height);
}
/**
* Replace Unicode characters with RTF Unicode control words
* @param source source text
* @return text with Unicode characters replaced
*/
private String handleUnicodeText(String sourceText)
{
StringBuilder unicodeText = new StringBuilder();
for(int i = 0; i < sourceText.length(); i++ )
{
long ch = sourceText.charAt(i);
if(ch > 127)
{
unicodeText.append("\\u" + ch + '?');
}
else if(ch == '\n')
{
unicodeText.append("\\line ");
}
else if(ch == '\\' || ch =='{' || ch =='}')
{
unicodeText.append('\\').append((char)ch);
}
else
{
unicodeText.append((char)ch);
}
}
return unicodeText.toString();
}
/**
* Export a image object
* @param printImage JasperReports image object (JRPrintImage)
* @throws JRException
* @throws IOException
*/
public void exportImage(JRPrintImage printImage) throws JRException, IOException
{
int leftPadding = printImage.getLineBox().getLeftPadding();
int topPadding = printImage.getLineBox().getTopPadding();
int rightPadding = printImage.getLineBox().getRightPadding();
int bottomPadding = printImage.getLineBox().getBottomPadding();
int availableImageWidth = printImage.getWidth() - leftPadding - rightPadding;
availableImageWidth = availableImageWidth < 0 ? 0 : availableImageWidth;
int availableImageHeight = printImage.getHeight() - topPadding - bottomPadding;
availableImageHeight = availableImageHeight < 0 ? 0 : availableImageHeight;
Renderable renderer = printImage.getRenderer();
if (
renderer != null
&& availableImageWidth > 0
&& availableImageHeight > 0
)
{
InternalImageProcessor imageProcessor =
new InternalImageProcessor(
printImage,
availableImageWidth,
availableImageHeight
);
InternalImageProcessorResult imageProcessorResult = null;
try
{
imageProcessorResult = imageProcessor.process(renderer);
}
catch (Exception e)
{
Renderable onErrorRenderer = getRendererUtil().handleImageError(e, printImage.getOnErrorTypeValue());
if (onErrorRenderer != null)
{
imageProcessorResult = imageProcessor.process(onErrorRenderer);
}
}
if (imageProcessorResult != null)//FIXMERTF draw image background for null images, like the other exporters do
{
int imageWidth = 0;
int imageHeight = 0;
int xoffset = 0;
int yoffset = 0;
float cropTop = 0;
float cropLeft = 0;
float cropBottom = 0;
float cropRight = 0;
int angle = 0;
switch (printImage.getScaleImageValue())
{
case CLIP:
{
float normalWidth = availableImageWidth;
float normalHeight = availableImageHeight;
Dimension2D dimension = imageProcessorResult.dimension;
if (dimension != null)
{
normalWidth = (int) dimension.getWidth();
normalHeight = (int) dimension.getHeight();
}
switch (printImage.getRotation())
{
case LEFT:
if (dimension == null)
{
normalWidth = availableImageHeight;
normalHeight = availableImageWidth;
}
switch (printImage.getHorizontalImageAlign())
{
case RIGHT :
cropLeft = (- availableImageHeight + normalWidth) / normalWidth;
cropRight = 0;
break;
case CENTER :
cropLeft = (- availableImageHeight + normalWidth) / normalWidth / 2;
cropRight = cropLeft;
break;
case LEFT :
default :
cropLeft = 0;
cropRight = (- availableImageHeight + normalWidth) / normalWidth;
break;
}
switch (printImage.getVerticalImageAlign())
{
case TOP :
cropTop = 0;
cropBottom = (- availableImageWidth + normalHeight) / normalHeight;
break;
case MIDDLE :
cropTop = (- availableImageWidth + normalHeight) / normalHeight / 2;
cropBottom = cropTop;
break;
case BOTTOM :
default :
cropTop = (- availableImageWidth + normalHeight) / normalHeight;
cropBottom = 0;
break;
}
angle = -90;
break;
case RIGHT:
if (dimension == null)
{
normalWidth = availableImageHeight;
normalHeight = availableImageWidth;
}
switch (printImage.getHorizontalImageAlign())
{
case RIGHT :
cropLeft = (- availableImageHeight + normalWidth) / normalWidth;
cropRight = 0;
break;
case CENTER :
cropLeft = (- availableImageHeight + normalWidth) / normalWidth / 2;
cropRight = cropLeft;
break;
case LEFT :
default :
cropLeft = 0;
cropRight = (- availableImageHeight + normalWidth) / normalWidth;
break;
}
switch (printImage.getVerticalImageAlign())
{
case TOP :
cropTop = 0;
cropBottom = (- availableImageWidth + normalHeight) / normalHeight;
break;
case MIDDLE :
cropTop = (- availableImageWidth + normalHeight) / normalHeight / 2;
cropBottom = cropTop;
break;
case BOTTOM :
default :
cropTop = (- availableImageWidth + normalHeight) / normalHeight;
cropBottom = 0;
break;
}
angle = 90;
break;
case UPSIDE_DOWN:
switch (printImage.getHorizontalImageAlign())
{
case RIGHT :
cropLeft = (- availableImageWidth + normalWidth) / normalWidth;
cropRight = 0;
break;
case CENTER :
cropLeft = (- availableImageWidth + normalWidth) / normalWidth / 2;
cropRight = cropLeft;
break;
case LEFT :
default :
cropLeft = 0;
cropRight = (- availableImageWidth + normalWidth) / normalWidth;
break;
}
switch (printImage.getVerticalImageAlign())
{
case TOP :
cropTop = 0;
cropBottom = (- availableImageHeight + normalHeight) / normalHeight;
break;
case MIDDLE :
cropTop = (- availableImageHeight + normalHeight) / normalHeight / 2;
cropBottom = cropTop;
break;
case BOTTOM :
default :
cropTop = (- availableImageHeight + normalHeight) / normalHeight;
cropBottom = 0;
break;
}
angle = 180;
break;
case NONE:
default:
switch (printImage.getHorizontalImageAlign())
{
case RIGHT :
cropLeft = (- availableImageWidth + normalWidth) / normalWidth;
cropRight = 0;
break;
case CENTER :
cropLeft = (- availableImageWidth + normalWidth) / normalWidth / 2;
cropRight = cropLeft;
break;
case LEFT :
default :
cropLeft = 0;
cropRight = (- availableImageWidth + normalWidth) / normalWidth;
break;
}
switch (printImage.getVerticalImageAlign())
{
case TOP :
cropTop = 0;
cropBottom = (- availableImageHeight + normalHeight) / normalHeight;
break;
case MIDDLE :
cropTop = (- availableImageHeight + normalHeight) / normalHeight / 2;
cropBottom = cropTop;
break;
case BOTTOM :
default :
cropTop = (- availableImageHeight + normalHeight) / normalHeight;
cropBottom = 0;
break;
}
angle = 0;
break;
}
imageWidth = availableImageWidth;
imageHeight = availableImageHeight;
break;
}
case FILL_FRAME:
{
imageWidth = availableImageWidth;
imageHeight = availableImageHeight;
switch (printImage.getRotation())
{
case LEFT:
angle = -90;
break;
case RIGHT:
angle = 90;
break;
case UPSIDE_DOWN:
angle = 180;
break;
case NONE:
default:
angle = 0;
break;
}
break;
}
case RETAIN_SHAPE:
default:
{
float normalWidth = availableImageWidth;
float normalHeight = availableImageHeight;
Dimension2D dimension = imageProcessorResult.dimension;
if (dimension != null)
{
normalWidth = (int) dimension.getWidth();
normalHeight = (int) dimension.getHeight();
}
float ratioX = 1f;
float ratioY = 1f;
switch (printImage.getRotation())
{
case LEFT:
if (dimension == null)
{
normalWidth = availableImageHeight;
normalHeight = availableImageWidth;
}
ratioX = availableImageWidth / normalHeight;
ratioY = availableImageHeight / normalWidth;
ratioX = ratioX < ratioY ? ratioX : ratioY;
ratioY = ratioX;
imageWidth = (int)(normalHeight * ratioX);
imageHeight = (int)(normalWidth * ratioY);
xoffset = (int) (ImageUtil.getYAlignFactor(printImage) * (availableImageWidth - imageWidth));
yoffset = (int) ((1f - ImageUtil.getXAlignFactor(printImage)) * (availableImageHeight - imageHeight));
angle = -90;
break;
case RIGHT:
if (dimension == null)
{
normalWidth = availableImageHeight;
normalHeight = availableImageWidth;
}
ratioX = availableImageWidth / normalHeight;
ratioY = availableImageHeight / normalWidth;
ratioX = ratioX < ratioY ? ratioX : ratioY;
ratioY = ratioX;
imageWidth = (int)(normalHeight * ratioX);
imageHeight = (int)(normalWidth * ratioY);
xoffset = (int) ((1f - ImageUtil.getYAlignFactor(printImage)) * (availableImageWidth - imageWidth));
yoffset = (int) (ImageUtil.getXAlignFactor(printImage) * (availableImageHeight - imageHeight));
angle = 90;
break;
case UPSIDE_DOWN:
ratioX = availableImageWidth / normalWidth;
ratioY = availableImageHeight / normalHeight;
ratioX = ratioX < ratioY ? ratioX : ratioY;
ratioY = ratioX;
imageWidth = (int)(normalWidth * ratioX);
imageHeight = (int)(normalHeight * ratioY);
xoffset = (int) ((1f - ImageUtil.getXAlignFactor(printImage)) * (availableImageWidth - imageWidth));
yoffset = (int) ((1f - ImageUtil.getYAlignFactor(printImage)) * (availableImageHeight - imageHeight));
angle = 180;
break;
case NONE:
default:
ratioX = availableImageWidth / normalWidth;
ratioY = availableImageHeight / normalHeight;
ratioX = ratioX < ratioY ? ratioX : ratioY;
ratioY = ratioX;
imageWidth = (int)(normalWidth * ratioX);
imageHeight = (int)(normalHeight * ratioY);
xoffset = (int) (ImageUtil.getXAlignFactor(printImage) * (availableImageWidth - imageWidth));
yoffset = (int) (ImageUtil.getYAlignFactor(printImage) * (availableImageHeight - imageHeight));
angle = 0;
break;
}
break;
}
}
startElement(printImage);
exportPen(printImage.getForecolor());//FIXMEBORDER should we have lineColor here, if at all needed?
finishElement();
boolean startedHyperlink = exportHyperlink(printImage);
contentWriter.write("{\\shp{\\*\\shpinst\\shpbxpage\\shpbypage\\shpwr5\\shpfhdr0\\shpfblwtxt0\\shpz");
contentWriter.write(String.valueOf(zorder++));
contentWriter.write("\\shpleft");
contentWriter.write(String.valueOf(LengthUtil.twip(printImage.getX() + leftPadding + xoffset + getOffsetX())));
contentWriter.write("\\shpright");
contentWriter.write(String.valueOf(LengthUtil.twip(printImage.getX() + leftPadding + xoffset + getOffsetX() + imageWidth)));
contentWriter.write("\\shptop");
contentWriter.write(String.valueOf(LengthUtil.twip(printImage.getY() + topPadding + yoffset + getOffsetY())));
contentWriter.write("\\shpbottom");
contentWriter.write(String.valueOf(LengthUtil.twip(printImage.getY() + topPadding + yoffset + getOffsetY() + imageHeight)));
contentWriter.write("{\\sp{\\sn shapeType}{\\sv 75}}");
contentWriter.write("{\\sp{\\sn fFilled}{\\sv 0}}");
contentWriter.write("{\\sp{\\sn Rotation}{\\sv " + (65536 * angle) + "}}");
contentWriter.write("{\\sp{\\sn fLockAspectRatio}{\\sv 0}}");
contentWriter.write("{\\sp{\\sn cropFromTop}{\\sv ");
contentWriter.write(String.valueOf((int)(65536 * cropTop)));
contentWriter.write("}}");
contentWriter.write("{\\sp{\\sn cropFromLeft}{\\sv ");
contentWriter.write(String.valueOf((int)(65536 * cropLeft)));
contentWriter.write("}}");
contentWriter.write("{\\sp{\\sn cropFromBottom}{\\sv ");
contentWriter.write(String.valueOf((int)(65536 * cropBottom)));
contentWriter.write("}}");
contentWriter.write("{\\sp{\\sn cropFromRight}{\\sv ");
contentWriter.write(String.valueOf((int)(65536 * cropRight)));
contentWriter.write("}}");
writeShapeHyperlink(printImage);
if(printImage.getAnchorName() != null)
{
writeAnchor(printImage.getAnchorName());
}
contentWriter.write("{\\sp{\\sn pib}{\\sv {\\pict");
if (imageProcessorResult.imageType == ImageTypeEnum.JPEG)
{
contentWriter.write("\\jpegblip");
}
else
{
contentWriter.write("\\pngblip");
}
contentWriter.write("\n");
ByteArrayInputStream bais = new ByteArrayInputStream(imageProcessorResult.imageData);
int count = 0;
int current = 0;
while ((current = bais.read()) != -1)
{
String helperStr = Integer.toHexString(current);
if (helperStr.length() < 2)
{
helperStr = "0" + helperStr;
}
contentWriter.write(helperStr);
count++;
if (count == 64)
{
contentWriter.write("\n");
count = 0;
}
}
contentWriter.write("\n}}}");
contentWriter.write("}}\n");
endHyperlink(startedHyperlink);
}
}
int x = printImage.getX() + getOffsetX();
int y = printImage.getY() + getOffsetY();
int width = printImage.getWidth();
int height = printImage.getHeight();
if (
printImage.getLineBox().getTopPen().getLineWidth() <= 0f &&
printImage.getLineBox().getLeftPen().getLineWidth() <= 0f &&
printImage.getLineBox().getBottomPen().getLineWidth() <= 0f &&
printImage.getLineBox().getRightPen().getLineWidth() <= 0f
)
{
if (printImage.getLinePen().getLineWidth() > 0f)
{
exportPen(printImage.getLinePen(), x, y, width, height);
}
}
else
{
exportBox(printImage.getLineBox(), x, y, width, height);
}
}
private class InternalImageProcessor
{
private final JRPrintElement imageElement;
private final RenderersCache imageRenderersCache;
private final boolean needDimension;
private final int availableImageWidth;
private final int availableImageHeight;
protected InternalImageProcessor(
JRPrintImage imageElement,
int availableImageWidth,
int availableImageHeight
)
{
this.imageElement = imageElement;
this.imageRenderersCache = imageElement.isUsingCache() ? renderersCache : new RenderersCache(getJasperReportsContext());
this.needDimension = imageElement.getScaleImageValue() != ScaleImageEnum.FILL_FRAME;
if (
imageElement.getRotation() == RotationEnum.LEFT
|| imageElement.getRotation() == RotationEnum.RIGHT
)
{
this.availableImageWidth = availableImageHeight;
this.availableImageHeight = availableImageWidth;
}
else
{
this.availableImageWidth = availableImageWidth;
this.availableImageHeight = availableImageHeight;
}
}
private InternalImageProcessorResult process(Renderable renderer) throws JRException
{
if (renderer instanceof ResourceRenderer)
{
renderer = imageRenderersCache.getLoadedRenderer((ResourceRenderer)renderer);
}
Dimension2D dimension = null;
if (needDimension)
{
DimensionRenderable dimensionRenderer = imageRenderersCache.getDimensionRenderable(renderer);
dimension = dimensionRenderer == null ? null : dimensionRenderer.getDimension(jasperReportsContext);
}
DataRenderable imageRenderer =
getRendererUtil().getImageDataRenderable(
imageRenderersCache,
renderer,
new Dimension(availableImageWidth, availableImageHeight),
ModeEnum.OPAQUE == imageElement.getModeValue() ? imageElement.getBackcolor() : null
);
byte[] imageData = imageRenderer.getData(jasperReportsContext);
return
new InternalImageProcessorResult(
imageData,
dimension,
JRTypeSniffer.getImageTypeValue(imageData)
);
}
}
private class InternalImageProcessorResult
{
protected final byte[] imageData;
protected final Dimension2D dimension;
protected final ImageTypeEnum imageType;
protected InternalImageProcessorResult(byte[] imageData, Dimension2D dimension, ImageTypeEnum imageType)
{
this.imageData = imageData;
this.dimension = dimension;
this.imageType = imageType;
}
}
/**
*
* @param frame
* @throws JRException
*/
public void exportFrame(JRPrintFrame frame) throws JRException, IOException {
int x = frame.getX() + getOffsetX();
int y = frame.getY() + getOffsetY();
int width = frame.getWidth();
int height = frame.getHeight();
startElement(frame);
exportPen(frame.getForecolor());
finishElement();
setFrameElementsOffset(frame, false);
exportElements(frame.getElements());
restoreElementOffsets();
exportBox(frame.getLineBox(), x, y, width, height);
}
protected void exportElements(Collection elements) throws JRException, IOException {
if (elements != null && elements.size() > 0) {
for (Iterator it = elements.iterator(); it.hasNext();) {
JRPrintElement element = it.next();
if (filter == null || filter.isToExport(element)) {
if (element instanceof JRPrintLine) {
exportLine((JRPrintLine)element);
}
else if (element instanceof JRPrintRectangle) {
exportRectangle((JRPrintRectangle)element);
}
else if (element instanceof JRPrintEllipse) {
exportEllipse((JRPrintEllipse)element);
}
else if (element instanceof JRPrintImage) {
exportImage((JRPrintImage)element);
}
else if (element instanceof JRPrintText) {
exportText((JRPrintText)element);
}
else if (element instanceof JRPrintFrame) {
exportFrame((JRPrintFrame)element);
}
else if (element instanceof JRGenericPrintElement) {
exportGenericElement((JRGenericPrintElement)element);
}
}
}
}
}
/**
*
*/
private void exportBox(JRLineBox box, int x, int y, int width, int height) throws IOException
{
exportTopPen(box.getTopPen(), box.getLeftPen(), box.getRightPen(), x, y, width, height);
exportLeftPen(box.getTopPen(), box.getLeftPen(), box.getBottomPen(), x, y, width, height);
exportBottomPen(box.getLeftPen(), box.getBottomPen(), box.getRightPen(), x, y, width, height);
exportRightPen(box.getTopPen(), box.getBottomPen(), box.getRightPen(), x, y, width, height);
}
/**
*
*/
private void exportPen(JRPen pen, int x, int y, int width, int height) throws IOException
{
exportTopPen(pen, pen, pen, x, y, width, height);
exportLeftPen(pen, pen, pen, x, y, width, height);
exportBottomPen(pen, pen, pen, x, y, width, height);
exportRightPen(pen, pen, pen, x, y, width, height);
}
/**
*
*/
private void exportTopPen(
JRPen topPen,
JRPen leftPen,
JRPen rightPen,
int x,
int y,
int width,
int height
) throws IOException
{
if (topPen.getLineWidth() > 0f)
{
exportBorder(
topPen,
x - leftPen.getLineWidth() / 2,
y,
width + (leftPen.getLineWidth() + rightPen.getLineWidth()) / 2,
0
);
//exportBorder(topPen, x, y + getAdjustment(topPen), width, 0);
}
}
/**
*
*/
private void exportLeftPen(
JRPen topPen,
JRPen leftPen,
JRPen bottomPen,
int x,
int y,
int width,
int height
) throws IOException
{
if (leftPen.getLineWidth() > 0f)
{
exportBorder(
leftPen,
x,
y - topPen.getLineWidth() / 2,
0,
height + (topPen.getLineWidth() + bottomPen.getLineWidth()) / 2
);
//exportBorder(leftPen, x + getAdjustment(leftPen), y, 0, height);
}
}
/**
*
*/
private void exportBottomPen(
JRPen leftPen,
JRPen bottomPen,
JRPen rightPen,
int x,
int y,
int width,
int height
) throws IOException
{
if (bottomPen.getLineWidth() > 0f)
{
exportBorder(
bottomPen,
x - leftPen.getLineWidth() / 2,
y + height,
width + (leftPen.getLineWidth() + rightPen.getLineWidth()) / 2,
0
);
//exportBorder(bottomPen, x, y + height - getAdjustment(bottomPen), width, 0);
}
}
/**
*
*/
private void exportRightPen(
JRPen topPen,
JRPen bottomPen,
JRPen rightPen,
int x,
int y,
int width,
int height
) throws IOException
{
if (rightPen.getLineWidth() > 0f)
{
exportBorder(
rightPen,
x + width,
y - topPen.getLineWidth() / 2,
0,
height + (topPen.getLineWidth() + bottomPen.getLineWidth()) / 2
);
//exportBorder(rightPen, x + width - getAdjustment(rightPen), y, 0, height);
}
}
protected void exportGenericElement(JRGenericPrintElement element)
{
GenericElementRtfHandler handler = (GenericElementRtfHandler)
GenericElementHandlerEnviroment.getInstance(getJasperReportsContext()).getElementHandler(
element.getGenericType(), RTF_EXPORTER_KEY);
if (handler != null)
{
handler.exportElement(exporterContext, element);
}
else
{
if (log.isDebugEnabled())
{
log.debug("No RTF generic element handler for "
+ element.getGenericType());
}
}
}
protected boolean exportHyperlink(JRPrintHyperlink link) throws IOException
{
String hl = null;
String local ="";
boolean result = false;
Boolean ignoreHyperlink = HyperlinkUtil.getIgnoreHyperlink(RtfReportConfiguration.PROPERTY_IGNORE_HYPERLINK, link);
if (ignoreHyperlink == null)
{
ignoreHyperlink = getCurrentItemConfiguration().isIgnoreHyperlink();
}
if (!ignoreHyperlink)
{
JRHyperlinkProducer customHandler = getHyperlinkProducer(link);
if (customHandler == null)
{
switch(link.getHyperlinkTypeValue())
{
case REFERENCE :
{
if (link.getHyperlinkReference() != null)
{
hl = link.getHyperlinkReference();
}
break;
}
case LOCAL_ANCHOR :
{
if (link.getHyperlinkAnchor() != null)
{
hl = link.getHyperlinkAnchor();
local = "\\\\l ";
}
break;
}
case LOCAL_PAGE :
{
if (link.getHyperlinkPage() != null)
{
hl = JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + link.getHyperlinkPage().toString();
local = "\\\\l ";
}
break;
}
case REMOTE_ANCHOR :
{
if (
link.getHyperlinkReference() != null &&
link.getHyperlinkAnchor() != null
)
{
hl = link.getHyperlinkReference() + "#" + link.getHyperlinkAnchor();
}
break;
}
case REMOTE_PAGE :
{
if (
link.getHyperlinkReference() != null &&
link.getHyperlinkPage() != null
)
{
hl = link.getHyperlinkReference() + "#" + JR_PAGE_ANCHOR_PREFIX + "0_" + link.getHyperlinkPage().toString();
}
break;
}
case NONE :
default :
{
break;
}
}
}
else
{
hl = customHandler.getHyperlink(link);
}
}
if (hl != null)
{
contentWriter.write("{\\field{\\*\\fldinst HYPERLINK " + local + "\"" + hl + "\"}{\\fldrslt ");
result = true;
}
return result;
}
protected void writeShapeHyperlink (JRPrintHyperlink link) throws IOException
{
String hlloc = null;
String hlfr = null;
String hlsrc = null;
Boolean ignoreHyperlink = HyperlinkUtil.getIgnoreHyperlink(RtfReportConfiguration.PROPERTY_IGNORE_HYPERLINK, link);
if (ignoreHyperlink == null)
{
ignoreHyperlink = getCurrentItemConfiguration().isIgnoreHyperlink();
}
if (!ignoreHyperlink)
{
JRHyperlinkProducer customHandler = getHyperlinkProducer(link);
if (customHandler == null)
{
switch(link.getHyperlinkTypeValue())
{
case REFERENCE :
{
if (link.getHyperlinkReference() != null)
{
hlsrc = link.getHyperlinkReference();
hlfr = hlsrc;
}
break;
}
case LOCAL_ANCHOR :
{
if (link.getHyperlinkAnchor() != null)
{
hlloc = link.getHyperlinkAnchor();
hlfr = hlloc;
}
break;
}
case LOCAL_PAGE :
{
if (link.getHyperlinkPage() != null)
{
hlloc = JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + link.getHyperlinkPage().toString();
hlfr = hlloc;
}
break;
}
case REMOTE_ANCHOR :
{
if (
link.getHyperlinkReference() != null &&
link.getHyperlinkAnchor() != null
)
{
hlsrc = link.getHyperlinkReference() + "#" + link.getHyperlinkAnchor();
hlfr = hlsrc;
}
break;
}
case REMOTE_PAGE :
{
if (
link.getHyperlinkReference() != null &&
link.getHyperlinkPage() != null
)
{
hlsrc = link.getHyperlinkReference() + "#" + JR_PAGE_ANCHOR_PREFIX + "0_" + link.getHyperlinkPage().toString();
hlfr = hlsrc;
}
break;
}
case NONE :
default :
{
break;
}
}
}
else
{
hlsrc = customHandler.getHyperlink(link);
hlfr = hlsrc;
}
}
if (hlfr != null)
{
contentWriter.write("{\\sp{\\sn fIsButton}{\\sv 1}}");
contentWriter.write("{\\sp{\\sn pihlShape}{\\sv {\\*\\hl");
contentWriter.write("{\\hlfr ");
contentWriter.write(hlfr);
contentWriter.write(" }");
if (hlloc != null)
{
contentWriter.write("{\\hlloc ");
contentWriter.write(hlloc);
contentWriter.write(" }");
}
if (hlsrc != null)
{
contentWriter.write("{\\hlsrc ");
contentWriter.write(hlsrc);
contentWriter.write(" }");
}
contentWriter.write("}}}");
}
}
protected void endHyperlink(boolean startedHyperlink) throws IOException
{
if(startedHyperlink)
{
contentWriter.write("}}");
}
}
protected void writeAnchor(String anchorName) throws IOException
{
contentWriter.write("{\\*\\bkmkstart ");
contentWriter.write(anchorName);
contentWriter.write("}{\\*\\bkmkend ");
contentWriter.write(anchorName);
contentWriter.write("}");
}
@Override
public String getExporterKey()
{
return RTF_EXPORTER_KEY;
}
@Override
public String getExporterPropertiesPrefix()
{
return RTF_EXPORTER_PROPERTIES_PREFIX;
}
}