ro.nextreports.engine.exporter.RtfExporter.java Source code

Java tutorial

Introduction

Here is the source code for ro.nextreports.engine.exporter.RtfExporter.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ro.nextreports.engine.exporter;

import java.awt.Color;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import ro.nextreports.engine.ReleaseInfoAdapter;
import ro.nextreports.engine.Report;
import ro.nextreports.engine.ReportLayout;
import ro.nextreports.engine.band.Band;
import ro.nextreports.engine.band.BandElement;
import ro.nextreports.engine.band.ExpressionBandElement;
import ro.nextreports.engine.band.Hyperlink;
import ro.nextreports.engine.band.HyperlinkBandElement;
import ro.nextreports.engine.band.ImageBandElement;
import ro.nextreports.engine.band.ImageColumnBandElement;
import ro.nextreports.engine.band.Padding;
import ro.nextreports.engine.band.PaperSize;
import ro.nextreports.engine.band.ReportBandElement;
import ro.nextreports.engine.band.VariableBandElement;
import ro.nextreports.engine.exporter.util.StyleFormatConstants;
import ro.nextreports.engine.exporter.util.variable.PageNoVariable;
import ro.nextreports.engine.exporter.util.variable.Variable;
import ro.nextreports.engine.exporter.util.variable.VariableFactory;
import ro.nextreports.engine.queryexec.QueryException;
import ro.nextreports.engine.util.PrefixSuffix;
import ro.nextreports.engine.util.StringUtil;

import com.lowagie.text.BadElementException;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.FontFactoryImp;
import com.lowagie.text.HeaderFooter;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.Table;
import com.lowagie.text.PageSize;
import com.lowagie.text.Image;
import com.lowagie.text.Anchor;
import com.lowagie.text.html.simpleparser.HTMLWorker;
import com.lowagie.text.html.simpleparser.StyleSheet;
import com.lowagie.text.rtf.RtfWriter2;
import com.lowagie.text.rtf.field.RtfPageNumber;
import com.lowagie.text.rtf.headerfooter.RtfHeaderFooter;
import com.lowagie.text.rtf.headerfooter.RtfHeaderFooterGroup;
import com.lowagie.text.rtf.table.RtfBorder;
import com.lowagie.text.rtf.table.RtfBorderGroup;
import com.lowagie.text.rtf.table.RtfCell;

/**
 * Created by IntelliJ IDEA. User: mihai.panaitescu Date: 24-Feb-2009 Time:
 * 11:46:10
 */
public class RtfExporter extends ResultExporter {

    public RtfExporter(ExporterBean bean) {
        super(bean);
    }

    protected void initExport() throws QueryException {
        if (!bean.isSubreport()) {
            Padding margins = bean.getReportLayout().getPagePadding();

            Rectangle rectangle;
            if (ReportLayout.CUSTOM.equals(bean.getReportLayout().getPageFormat())) {
                PaperSize customSize = bean.getReportLayout().getPaperSize();
                rectangle = new Rectangle(customSize.getWidthPoints(), customSize.getHeightPoints());
            } else {
                rectangle = PageSize.getRectangle(getPageFormat());
            }

            document = new Document(rectangle, getPoints(margins.getLeft()), getPoints(margins.getRight()),
                    getPoints(margins.getTop()), getPoints(margins.getBottom()));
            if (bean.getReportLayout().getOrientation() == LANDSCAPE) {
                document.setPageSize(rectangle.rotate());
            }
            RtfWriter2 writer2 = RtfWriter2.getInstance(document, getOut());
        }
        try {
            if (!bean.isSubreport()) {
                buildHeader();
                buildFooter();
                addMetaData();
                document.open();
            }
            table = buildRtfTable(PRINT_DOCUMENT);
        } catch (DocumentException e) {
            e.printStackTrace();
            throw new QueryException(e);
        }
    }

    // Metadata methods must be called after establishing the document writer
    // and prior
    // to opening the document
    private void addMetaData() {
        document.addTitle(getDocumentTitle());
        document.addAuthor(ReleaseInfoAdapter.getCompany());
        document.addCreator("NextReports " + ReleaseInfoAdapter.getVersionNumber());
        document.addSubject("Created by NextReports Designer" + ReleaseInfoAdapter.getVersionNumber());
        document.addCreationDate();
        document.addKeywords(ReleaseInfoAdapter.getHome());
    }

    protected void finishExport() {
        if (!bean.isSubreport()) {
            try {
                if (table != null) {
                    document.add(table);
                }
            } catch (DocumentException e) {
                e.printStackTrace();
            } finally {
                table = null;
                document.close();
            }
        }
    }

    protected void close() {
        if (!bean.isSubreport()) {
            document.close();
        }
    }

    protected void flush() {
    }

    protected void flushNow() {
    }

    protected Set<CellElement> getIgnoredCells(Band band) {
        return getIgnoredCellElements(band);
    }

    protected void exportCell(String bandName, BandElement bandElement, Object value, int gridRow, int row,
            int column, int cols, int rowSpan, int colSpan, boolean isImage) {
        if (!bean.isSubreport()) {
            if (ReportLayout.PAGE_HEADER_BAND_NAME.equals(bandName)) {
                header.addCell(renderRtfCell(bandElement, value, gridRow, column, rowSpan, colSpan, isImage));
            } else if (ReportLayout.PAGE_FOOTER_BAND_NAME.equals(bandName)) {
                footer.addCell(renderRtfCell(bandElement, value, gridRow, column, rowSpan, colSpan, isImage));
            } else {
                table.addCell(renderRtfCell(bandElement, value, gridRow, column, rowSpan, colSpan, isImage));
            }
        } else {
            table.addCell(renderRtfCell(bandElement, value, gridRow, column, rowSpan, colSpan, isImage));
        }
    }

    protected void afterRowExport() {
    }

    protected String getNullElement() {
        return "";
    }

    private int fragmentsize = 15000;
    private Document document;
    private Table table;
    private Table header;
    private Table footer;

    private RtfCell renderRtfCell(BandElement bandElement, Object value, int gridRow, int gridColumn, int rowSpan,
            int colSpan, boolean image) {
        Map<String, Object> style = buildCellStyleMap(bandElement, value, gridRow, gridColumn, colSpan);
        String stringValue;

        FontFactoryImp fact = new FontFactoryImp();
        Font fnt;
        if (bandElement != null) {
            String fontName = (String) style.get(StyleFormatConstants.FONT_NAME_KEY);
            int size = ((Float) style.get(StyleFormatConstants.FONT_SIZE)).intValue();
            fnt = getFont(fontName, size);
        } else {
            fnt = getFont(10);
        }

        RtfCell cell = null;
        boolean specialCell = false;
        if (image) {
            try {
                if (value == null) {
                    cell = new RtfCell(new Phrase(IMAGE_NOT_FOUND));
                } else {
                    ImageBandElement ibe = (ImageBandElement) bandElement;
                    byte[] imageBytes = getImage((String) value, ibe.getWidth(), ibe.getHeight());
                    cell = new RtfCell(Image.getInstance(imageBytes));
                }
            } catch (Exception e) {
                cell = new RtfCell(IMAGE_NOT_LOADED);
            }
            specialCell = true;
        } else if (bandElement instanceof HyperlinkBandElement) {
            Hyperlink hyperlink = ((HyperlinkBandElement) bandElement).getHyperlink();
            Anchor anchor = new Anchor(hyperlink.getText(), fnt);
            anchor.setReference(hyperlink.getUrl());
            Phrase ph = new Phrase();
            ph.add(anchor);
            try {
                cell = new RtfCell(ph);
            } catch (BadElementException e) {
                e.printStackTrace();
                cell = new RtfCell(hyperlink.getText());
            }
            specialCell = true;
        } else if (bandElement instanceof ReportBandElement) {
            Report report = ((ReportBandElement) bandElement).getReport();
            ExporterBean eb = null;
            try {
                eb = getSubreportExporterBean(report);
                RtfExporter subExporter = new RtfExporter(eb);
                subExporter.export();
                Table innerTable = subExporter.getTable();
                cell = new RtfCell(innerTable);
            } catch (Exception e) {
                cell = new RtfCell();
                e.printStackTrace();
            } finally {
                if ((eb != null) && (eb.getResult() != null)) {
                    eb.getResult().close();
                }
            }
            specialCell = true;
        } else if (bandElement instanceof VariableBandElement) {
            VariableBandElement vbe = (VariableBandElement) bandElement;
            Variable var = VariableFactory.getVariable(vbe.getVariable());
            if (var instanceof PageNoVariable) {
                cell = new RtfCell();
                cell.add(new RtfPageNumber());
                cell.setBorderWidth(0);
                specialCell = true;
            }
        } else if (bandElement instanceof ExpressionBandElement) {
            // special case pageNo inside an expression
            // bandName is not important here (it is used for groupRow
            // computation)
            PrefixSuffix pf = interpretPageNo(bandElement);
            if (pf != null) {
                updateFont(fnt, style);
                cell = new RtfCell();
                if (!"".equals(pf.getPrefix())) {
                    cell.add(new Phrase(pf.getPrefix(), fnt));
                }
                cell.add(new RtfPageNumber(fnt));
                if (!"".equals(pf.getSuffix())) {
                    cell.add(new Phrase(pf.getSuffix(), fnt));
                }
                specialCell = true;
            }
        } else if (bandElement instanceof ImageColumnBandElement) {
            try {
                String v = StringUtil.getValueAsString(value, null);
                if (StringUtil.BLOB.equals(v)) {
                    cell = new RtfCell(new Phrase(StringUtil.BLOB));
                } else {
                    ImageColumnBandElement icbe = (ImageColumnBandElement) bandElement;
                    byte[] imageD = StringUtil.decodeImage(v);
                    byte[] imageBytes = getImage(imageD, icbe.getWidth(), icbe.getHeight());
                    cell = new RtfCell(Image.getInstance(imageBytes));
                }
            } catch (Exception e) {
                cell = new RtfCell(IMAGE_NOT_LOADED);
            }
            specialCell = true;
        }
        if (!specialCell) {
            if (style.containsKey(StyleFormatConstants.PATTERN)) {
                stringValue = StringUtil.getValueAsString(value, (String) style.get(StyleFormatConstants.PATTERN),
                        getReportLanguage());
            } else {
                stringValue = StringUtil.getValueAsString(value, null, getReportLanguage());
            }
            if (stringValue == null) {
                stringValue = "";
            }
            Phrase ph;
            if (stringValue.startsWith("<html>")) {
                StringReader reader = new StringReader(stringValue);
                List<Element> elems = new ArrayList<Element>();
                try {
                    elems = HTMLWorker.parseToList(reader, new StyleSheet());
                    ph = new Phrase();
                    for (int i = 0; i < elems.size(); i++) {
                        Element elem = (Element) elems.get(i);
                        ph.add(elem);
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    ph = new Phrase(stringValue, fnt);
                }
            } else {
                ph = new Phrase(stringValue, fnt);
            }

            try {
                cell = new RtfCell(ph);
            } catch (BadElementException e) {
                e.printStackTrace();
                cell = new RtfCell(stringValue);
            }
        }

        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);

        if (colSpan > 1) {
            cell.setColspan(colSpan);
        }

        if (rowSpan > 1) {
            cell.setRowspan(rowSpan);
        }

        setCellStyle(fnt, style, cell);

        return cell;
    }

    private void updateFont(Font fnt, Map<String, Object> style) {
        if (style != null) {
            if (style.containsKey(StyleFormatConstants.FONT_FAMILY_KEY)) {
                String val = (String) style.get(StyleFormatConstants.FONT_FAMILY_KEY);
                fnt.setFamily(val);
            }
            if (style.containsKey(StyleFormatConstants.FONT_SIZE)) {
                Float val = (Float) style.get(StyleFormatConstants.FONT_SIZE);
                fnt.setSize(val);
            }
            if (style.containsKey(StyleFormatConstants.FONT_COLOR)) {
                Color val = (Color) style.get(StyleFormatConstants.FONT_COLOR);
                fnt.setColor(val);
            }
            if (style.containsKey(StyleFormatConstants.FONT_STYLE_KEY)) {
                if (StyleFormatConstants.FONT_STYLE_NORMAL.equals(style.get(StyleFormatConstants.FONT_STYLE_KEY))) {
                    fnt.setStyle(com.lowagie.text.Font.NORMAL);
                }
                if (StyleFormatConstants.FONT_STYLE_BOLD.equals(style.get(StyleFormatConstants.FONT_STYLE_KEY))) {
                    fnt.setStyle(com.lowagie.text.Font.BOLD);
                }
                if (StyleFormatConstants.FONT_STYLE_ITALIC.equals(style.get(StyleFormatConstants.FONT_STYLE_KEY))) {
                    fnt.setStyle(com.lowagie.text.Font.ITALIC);
                }
                if (StyleFormatConstants.FONT_STYLE_BOLDITALIC
                        .equals(style.get(StyleFormatConstants.FONT_STYLE_KEY))) {
                    fnt.setStyle(com.lowagie.text.Font.BOLDITALIC);
                }
            }
        }
    }

    private void setCellStyle(Font fnt, Map<String, Object> style, RtfCell cell) {
        if (style != null) {
            updateFont(fnt, style);
            if (style.containsKey(StyleFormatConstants.BACKGROUND_COLOR)) {
                Color val = (Color) style.get(StyleFormatConstants.BACKGROUND_COLOR);
                cell.setBackgroundColor(val);
            }
            if (style.containsKey(StyleFormatConstants.HORIZONTAL_ALIGN_KEY)) {
                if (StyleFormatConstants.HORIZONTAL_ALIGN_LEFT
                        .equals(style.get(StyleFormatConstants.HORIZONTAL_ALIGN_KEY))) {
                    cell.setHorizontalAlignment(Element.ALIGN_LEFT);
                }
                if (StyleFormatConstants.HORIZONTAL_ALIGN_RIGHT
                        .equals(style.get(StyleFormatConstants.HORIZONTAL_ALIGN_KEY))) {
                    cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
                }
                if (StyleFormatConstants.HORIZONTAL_ALIGN_CENTER
                        .equals(style.get(StyleFormatConstants.HORIZONTAL_ALIGN_KEY))) {
                    cell.setHorizontalAlignment(Element.ALIGN_CENTER);
                }
            }

            if (style.containsKey(StyleFormatConstants.VERTICAL_ALIGN_KEY)) {
                if (StyleFormatConstants.VERTICAL_ALIGN_TOP
                        .equals(style.get(StyleFormatConstants.VERTICAL_ALIGN_KEY))) {
                    cell.setVerticalAlignment(Element.ALIGN_TOP);
                }
                if (StyleFormatConstants.VERTICAL_ALIGN_MIDDLE
                        .equals(style.get(StyleFormatConstants.VERTICAL_ALIGN_KEY))) {
                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                }
                if (StyleFormatConstants.VERTICAL_ALIGN_BOTTOM
                        .equals(style.get(StyleFormatConstants.VERTICAL_ALIGN_KEY))) {
                    cell.setVerticalAlignment(Element.ALIGN_BOTTOM);
                }
            }
            // if (style.containsKey(StyleFormatConstants.PADDING_LEFT)) {
            // Float val = (Float) style.get(StyleFormatConstants.PADDING_LEFT);
            // cell.setPaddingLeft(val);
            // }
            // if (style.containsKey(StyleFormatConstants.PADDING_RIGHT)) {
            // Float val = (Float)
            // style.get(StyleFormatConstants.PADDING_RIGHT);
            // cell.setPaddingRight(val);
            // }
            // if (style.containsKey(StyleFormatConstants.PADDING_TOP)) {
            // Float val = (Float) style.get(StyleFormatConstants.PADDING_TOP);
            // cell.setPaddingTop(val);
            // }
            // if (style.containsKey(StyleFormatConstants.PADDING_BOTTOM)) {
            // Float val = (Float)
            // style.get(StyleFormatConstants.PADDING_BOTTOM);
            // cell.setPaddingBottom(val);
            // }
            cell.setBorderWidth(0);

            Float val = Float.valueOf(1);
            RtfBorderGroup bg = new RtfBorderGroup();
            if (style.containsKey(StyleFormatConstants.BORDER_LEFT)) {
                val = (Float) style.get(StyleFormatConstants.BORDER_LEFT);
                Color color = (Color) style.get(StyleFormatConstants.BORDER_LEFT_COLOR);
                bg.addBorder(Rectangle.LEFT, RtfBorder.BORDER_SINGLE, val, color);
            }
            if (style.containsKey(StyleFormatConstants.BORDER_RIGHT)) {
                val = (Float) style.get(StyleFormatConstants.BORDER_RIGHT);
                Color color = (Color) style.get(StyleFormatConstants.BORDER_RIGHT_COLOR);
                bg.addBorder(Rectangle.RIGHT, RtfBorder.BORDER_SINGLE, val, color);
            }
            if (style.containsKey(StyleFormatConstants.BORDER_TOP)) {
                val = (Float) style.get(StyleFormatConstants.BORDER_TOP);
                Color color = (Color) style.get(StyleFormatConstants.BORDER_TOP_COLOR);
                bg.addBorder(Rectangle.TOP, RtfBorder.BORDER_SINGLE, val, color);
            }
            if (style.containsKey(StyleFormatConstants.BORDER_BOTTOM)) {
                val = (Float) style.get(StyleFormatConstants.BORDER_BOTTOM);
                Color color = (Color) style.get(StyleFormatConstants.BORDER_BOTTOM_COLOR);
                bg.addBorder(Rectangle.BOTTOM, RtfBorder.BORDER_SINGLE, val, color);
            }
            cell.setBorders(bg);

            // cell.setNoWrap(true);
            // if (bandElement != null) {
            // if (bandElement.isWrapText()) {
            // cell.setNoWrap(false);
            // }
            // }
        }
    }

    private Font getFont(String fontName, int size) {
        return FontFactory.getFont(fontName, size);
    }

    private Font getFont(int size) {
        return FontFactory.getFont(FontFactory.TIMES, size);
    }

    // type : PRINT_DOCUMENT, PRINT_PAGE_HEADER, PRINT_PAGE_FOOTER
    private Table buildRtfTable(int type) throws DocumentException {
        List<Band> bands = new ArrayList<Band>();
        if (type == 1) {
            bands.add(getReportLayout().getPageHeaderBand());
        } else if (type == 2) {
            bands.add(getReportLayout().getPageFooterBand());
        } else {
            bands = getReportLayout().getDocumentBands();
        }
        int totalRows = 0;
        int totalColumns = 0;
        for (Band band : bands) {
            totalRows += band.getRowCount();
            int cols = band.getColumnCount();
            if (cols > totalColumns) {
                totalColumns = cols;
            }
        }

        // no page header or no page footer
        if (totalColumns == 0) {
            return null;
        }
        Table datatable = new Table(totalColumns);
        int[] headerwidths = new int[totalColumns]; // %
        int size = 100 / totalColumns;
        int totalWidth = 0;
        for (int i = 0; i < totalColumns; i++) {
            if (bean.getReportLayout().isUseSize()) {
                headerwidths[i] = bean.getReportLayout().getColumnsWidth().get(i);
            } else {
                headerwidths[i] = size;
            }
            totalWidth += headerwidths[i];
        }

        if (bean.getReportLayout().isUseSize()) {
            float pixels = A4_PORTRAIT_PIXELS;
            if (bean.getReportLayout().getOrientation() == LANDSCAPE) {
                pixels = A4_LANDSCAPE_PIXELS;
            }
            float percentage = totalWidth * 100 / pixels;
            // do not allow to go outside an A4 frame
            if (percentage > 100) {
                percentage = 100;
            }
            if (!ReportLayout.CUSTOM.equals(bean.getReportLayout().getPageFormat())) {
                datatable.setWidth(percentage);
            }
            datatable.setWidths(headerwidths);
        } else {
            datatable.setWidth(100);
        }

        datatable.setPadding(2);
        if (type == PRINT_DOCUMENT) {
            writeHeader(datatable);
        }
        return datatable;
    }

    private void writeHeader(Table datatable) {
        if (bean.getReportLayout().isHeaderOnEveryPage()) {
            int headerNo = bean.getReportLayout().getHeaderBand().getRowCount();
            if (headerNo > 0) {
                datatable.setLastHeaderRow(headerNo);
            }
        }
    }

    private void buildHeader() throws DocumentException, QueryException {
        header = buildRtfTable(PRINT_PAGE_HEADER);
        if (header == null) {
            return;
        }
        printPageHeaderBand();
        HeaderFooter hf = new RtfHeaderFooter(header);
        document.setHeader(hf);
    }

    private void buildFooter() throws DocumentException, QueryException {
        footer = buildRtfTable(PRINT_PAGE_FOOTER);
        if (footer == null) {
            return;
        }
        printPageFooterBand();
        RtfHeaderFooterGroup footerGroup = new RtfHeaderFooterGroup();
        RtfHeaderFooter hf = new RtfHeaderFooter(footer);
        footerGroup.setHeaderFooter(hf, RtfHeaderFooter.DISPLAY_ALL_PAGES);
        document.setFooter(footerGroup);
    }

    protected void newPage() {
        if (!bean.isSubreport()) {
            try {
                document.add(table);
                document.newPage();
                table.deleteAllRows();
                if (bean.getReportLayout().isHeaderOnEveryPage()) {
                    try {
                        printHeaderBand();
                    } catch (QueryException e) {
                        e.printStackTrace();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private String getPageFormat() {
        String format = bean.getReportLayout().getPageFormat();
        // not supported by RTF
        if (ReportLayout.A0.equals(format) || ReportLayout.A1.equals(format)) {
            format = ReportLayout.A2;
        }
        return format;
    }

    public Table getTable() {
        return table;
    }

}