uk.co.spudsoft.birt.emitters.excel.handlers.AbstractRealTableCellHandler.java Source code

Java tutorial

Introduction

Here is the source code for uk.co.spudsoft.birt.emitters.excel.handlers.AbstractRealTableCellHandler.java

Source

/*************************************************************************************
 * Copyright (c) 2011, 2012, 2013 James Talbut.
 *  jim-emitters@spudsoft.co.uk
 *  
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     James Talbut - Initial implementation.
 ************************************************************************************/

package uk.co.spudsoft.birt.emitters.excel.handlers;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.util.CellRangeAddress;
import org.eclipse.birt.core.exception.BirtException;
import org.eclipse.birt.report.engine.content.IAutoTextContent;
import org.eclipse.birt.report.engine.content.ICellContent;
import org.eclipse.birt.report.engine.content.IContainerContent;
import org.eclipse.birt.report.engine.content.IDataContent;
import org.eclipse.birt.report.engine.content.IElement;
import org.eclipse.birt.report.engine.content.IForeignContent;
import org.eclipse.birt.report.engine.content.IImageContent;
import org.eclipse.birt.report.engine.content.ILabelContent;
import org.eclipse.birt.report.engine.content.IListContent;
import org.eclipse.birt.report.engine.content.ITableContent;
import org.eclipse.birt.report.engine.content.ITextContent;
import org.eclipse.birt.report.engine.content.impl.CellContent;
import org.eclipse.birt.report.engine.content.impl.TableContent;
import org.eclipse.birt.report.engine.css.engine.StyleConstants;
import org.eclipse.birt.report.engine.emitter.IContentEmitter;
import org.eclipse.birt.report.engine.ir.CellDesign;
import org.eclipse.birt.report.engine.layout.pdf.util.HTML2Content;

import uk.co.spudsoft.birt.emitters.excel.Area;
import uk.co.spudsoft.birt.emitters.excel.Coordinate;
import uk.co.spudsoft.birt.emitters.excel.EmitterServices;
import uk.co.spudsoft.birt.emitters.excel.ExcelEmitter;
import uk.co.spudsoft.birt.emitters.excel.HandlerState;
import uk.co.spudsoft.birt.emitters.excel.framework.Logger;

public class AbstractRealTableCellHandler extends CellContentHandler {

    protected int column;
    private AbstractRealTableRowHandler parentRow;
    private boolean containsTable;

    public AbstractRealTableCellHandler(IContentEmitter emitter, Logger log, IHandler parent, ICellContent cell) {
        super(emitter, log, parent, cell);
        column = cell.getColumn();
    }

    @Override
    public void notifyHandler(HandlerState state) {
        if (parentRow != null) {
            parentRow.resumeRow(state);
            resumeCell(state);
            parentRow = null;
        }
    }

    @Override
    public void startCell(HandlerState state, ICellContent cell) throws BirtException {
        log.debug("Cell - " + "BIRT[" + cell.getRow()
                + (cell.getRowSpan() > 1 ? "-" + (cell.getRow() + cell.getRowSpan() - 1) : "") + ","
                + cell.getColumn() + (cell.getColSpan() > 1 ? "-" + (cell.getColumn() + cell.getColSpan() - 1) : "")
                + "]" + " state[" + state.rowNum + "," + state.colNum + "]");
        resumeCell(state);
    }

    @Override
    public void endCell(HandlerState state, ICellContent cell) throws BirtException {
        if (cell.getBookmark() != null) {
            createName(state, prepareName(cell.getBookmark()), state.rowNum, state.colNum, state.rowNum,
                    state.colNum);
        }

        interruptCell(state, !containsTable);
    }

    public void resumeCell(HandlerState state) {
    }

    public void interruptCell(HandlerState state, boolean includeFormatOnly) throws BirtException {

        if (state == null) {
            System.err.println("state == null");
        } else if (state.currentSheet == null) {
            System.err.println("state.currentSheet == null");
        } else if (state.currentSheet.getRow(state.rowNum) == null) {
            System.err.println("state.currentSheet.getRow(" + state.rowNum + ") == null");
        }

        if ((lastValue != null) || includeFormatOnly) {
            Cell currentCell = state.currentSheet.getRow(state.rowNum).getCell(column);
            if (currentCell == null) {
                log.debug("Creating cell[", state.rowNum, ",", column, "]");
                currentCell = state.currentSheet.getRow(state.rowNum).createCell(column);
            }

            ICellContent cell = (ICellContent) element;
            Area area = null;

            if ((cell.getColSpan() > 1) || (cell.getRowSpan() > 1)) {

                int endRow = state.rowNum + cell.getRowSpan() - 1;
                int endCol = state.colNum + cell.getColSpan() - 1;

                if (cell.getRowSpan() > 1) {
                    log.debug("Adding row span [", state.rowNum, ",", state.colNum, "] to [", endRow, ",", endCol,
                            "]");
                    area = state.addRowSpan(state.rowNum, state.colNum, endRow, endCol);
                }

                int offset = state.computeNumberSpanBefore(state.rowNum, state.colNum);
                log.debug("Offset for [", state.rowNum, ",", state.colNum, "] calculated as ", offset);
                log.debug("Merging [", state.rowNum, ",", state.colNum + offset, "] to [", endRow, ",",
                        endCol + offset, "]");
                log.debug("Should be merging ? [", state.rowNum, ",", column, "] to [", endRow, ",",
                        column + cell.getColSpan() - 1, "]");
                // CellRangeAddress newMergedRegion = new CellRangeAddress( state.rowNum, endRow, state.colNum + offset, endCol + offset );
                CellRangeAddress newMergedRegion = new CellRangeAddress(state.rowNum, endRow, column,
                        column + cell.getColSpan() - 1);
                state.currentSheet.addMergedRegion(newMergedRegion);

                colSpan = cell.getColSpan();
            }

            endCellContent(state, cell, lastElement, currentCell, area);
        }

        if (state.cellIsMergedWithBorders(state.rowNum, column)) {
            int absoluteColumn = column;
            ++state.colNum;
            --colSpan;
            while (colSpan > 0) {
                ++absoluteColumn;
                log.debug("Creating cell[", state.rowNum, ",", absoluteColumn, "]");
                Cell currentCell = state.currentSheet.getRow(state.rowNum).createCell(absoluteColumn);
                endCellContent(state, null, null, currentCell, null);
                ++state.colNum;
                --colSpan;
            }
        } else {
            state.colNum += colSpan;
        }

        state.setHandler(parent);
    }

    @Override
    public void startContainer(HandlerState state, IContainerContent container) throws BirtException {
        // log.debug( "Container display = " + getStyleProperty( container, StyleConstants.STYLE_DISPLAY, "block") );
        if (!"inline".equals(getStyleProperty(container, StyleConstants.STYLE_DISPLAY, "block"))) {
            lastCellContentsWasBlock = true;
        }
    }

    @Override
    public void endContainer(HandlerState state, IContainerContent container) throws BirtException {
        // log.debug( "Container display = " + getStyleProperty( container, StyleConstants.STYLE_DISPLAY, "block") );
        if (!"inline".equals(getStyleProperty(container, StyleConstants.STYLE_DISPLAY, "block"))) {
            lastCellContentsWasBlock = true;
        }
    }

    private TableContent cellDesignsTableContent() {
        IElement current = element;
        while ((current != null) && !(current instanceof TableContent)) {
            current = current.getParent();
        }
        return (TableContent) current;
    }

    @Override
    public void startTable(HandlerState state, ITableContent table) throws BirtException {
        int colSpan = ((ICellContent) element).getColSpan();
        int rowSpan = ((ICellContent) element).getRowSpan();
        ITableHandler tableHandler = getAncestor(ITableHandler.class);
        TableContent myTableContent = cellDesignsTableContent();

        if ((tableHandler != null) && (tableHandler.getColumnCount() == colSpan)
                && (1 == ((CellDesign) ((CellContent) table.getParent()).getGenerateBy()).getContentCount())) {
            // Parent row contains only one item

            containsTable = true;
            parentRow = getAncestor(AbstractRealTableRowHandler.class);
            interruptCell(state, false);
            parentRow.interruptRow(state);

            state.setHandler(new NestedTableHandler(log, this, table, rowSpan));
            state.getHandler().startTable(state, table);
        } else if ((tableHandler != null) && (myTableContent != null) && (table.getParent() instanceof CellContent)
                && (((CellContent) table.getParent()).getGenerateBy() instanceof CellDesign)
                && (((CellDesign) ((CellContent) table.getParent()).getGenerateBy()).getColumn()
                        + 1 == myTableContent.getColumnCount())
                && EmitterServices.booleanOption(state.getRenderOptions(), table,
                        ExcelEmitter.NEST_TABLE_IN_LAST_CELL, false)) {
            // This is last cell in row

            colSpan = table.getColumnCount();
            containsTable = true;
            parentRow = getAncestor(AbstractRealTableRowHandler.class);
            interruptCell(state, false);
            // parentRow.interruptRow(state);

            state.setHandler(new NestedTableHandler(log, this, table, rowSpan));
            state.getHandler().startTable(state, table);
        } else if ((tableHandler != null) && (table.getColumnCount() <= colSpan)) {
            // This cell is merged over same number of columns as new table

            containsTable = true;
            parentRow = getAncestor(AbstractRealTableRowHandler.class);
            interruptCell(state, false);

            removeMergedCell(state, state.rowNum, state.colNum);

            NestedTableHandler nestedTableHandler = new NestedTableHandler(log, this, table, rowSpan);
            nestedTableHandler.setInserted(true);
            state.setHandler(nestedTableHandler);
            state.getHandler().startTable(state, table);

        } else {
            state.setHandler(new FlattenedTableHandler(this, log, this, table));
            state.getHandler().startTable(state, table);
        }
    }

    @Override
    public void startList(HandlerState state, IListContent list) throws BirtException {
        int colSpan = ((ICellContent) element).getColSpan();
        ITableHandler tableHandler = getAncestor(ITableHandler.class);
        if ((tableHandler != null) && (tableHandler.getColumnCount() == colSpan)
                && (1 == ((CellDesign) ((CellContent) list.getParent()).getGenerateBy()).getContentCount())) {

            containsTable = true;
            parentRow = getAncestor(AbstractRealTableRowHandler.class);
            interruptCell(state, false);
            parentRow.interruptRow(state);

            state.colNum = column;
            state.setHandler(new NestedListHandler(log, this, list));
            state.getHandler().startList(state, list);
        } else {
            state.setHandler(new FlattenedListHandler(this, log, this, list));
            state.getHandler().startList(state, list);
        }
    }

    @Override
    public void emitText(HandlerState state, ITextContent text) throws BirtException {
        String textText = text.getText();
        log.debug("text:", textText);
        emitContent(state, text, textText,
                (!"inline".equals(getStyleProperty(text, StyleConstants.STYLE_DISPLAY, "block"))));
    }

    @Override
    public void emitData(HandlerState state, IDataContent data) throws BirtException {
        emitContent(state, data, data.getValue(),
                (!"inline".equals(getStyleProperty(data, StyleConstants.STYLE_DISPLAY, "block"))));
    }

    @Override
    public void emitLabel(HandlerState state, ILabelContent label) throws BirtException {
        // String labelText = ( label.getLabelText() != null ) ? label.getLabelText() : label.getText();
        String labelText = (label.getText() != null) ? label.getText() : label.getLabelText();
        log.debug("labelText:", labelText);
        emitContent(state, label, labelText,
                (!"inline".equals(getStyleProperty(label, StyleConstants.STYLE_DISPLAY, "block"))));
    }

    @Override
    public void emitAutoText(HandlerState state, IAutoTextContent autoText) throws BirtException {
        emitContent(state, autoText, autoText.getText(),
                (!"inline".equals(getStyleProperty(autoText, StyleConstants.STYLE_DISPLAY, "block"))));
    }

    @Override
    public void emitForeign(HandlerState state, IForeignContent foreign) throws BirtException {

        log.debug("Handling foreign content of type ", foreign.getRawType());
        if (IForeignContent.HTML_TYPE.equalsIgnoreCase(foreign.getRawType())) {
            HTML2Content.html2Content(foreign);
            contentVisitor.visitChildren(foreign, null);
        }
    }

    @Override
    public void emitImage(HandlerState state, IImageContent image) throws BirtException {
        boolean imageCanSpan = false;

        int colSpan = ((ICellContent) element).getColSpan();
        ITableHandler tableHandler = getAncestor(ITableHandler.class);
        if ((tableHandler != null) && (tableHandler.getColumnCount() == colSpan)
                && (1 == ((CellDesign) ((CellContent) image.getParent()).getGenerateBy()).getContentCount())) {
            imageCanSpan = true;
        }
        recordImage(state, new Coordinate(state.rowNum, column), image, imageCanSpan);
        lastElement = image;
    }

}