Package org.eclipse.nebula.widgets.nattable.extension.poi

Source Code of org.eclipse.nebula.widgets.nattable.extension.poi.PoiExcelExporter

/*******************************************************************************
* Copyright (c) 2012 Original authors and others.
* 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:
*     Original authors and others - initial API and implementation
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.extension.poi;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.export.ExportConfigAttributes;
import org.eclipse.nebula.widgets.nattable.export.ILayerExporter;
import org.eclipse.nebula.widgets.nattable.export.IOutputStreamProvider;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.painter.cell.CellPainterWrapper;
import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.VerticalTextPainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.decorator.CellPainterDecorator;
import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes;
import org.eclipse.nebula.widgets.nattable.style.CellStyleProxy;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.style.HorizontalAlignmentEnum;
import org.eclipse.nebula.widgets.nattable.style.VerticalAlignmentEnum;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.widgets.Shell;

public abstract class PoiExcelExporter implements ILayerExporter {

    private final IOutputStreamProvider outputStreamProvider;

    private Map<ExcelCellStyleAttributes, CellStyle> xlCellStyles;

    protected Workbook xlWorkbook;
    protected int sheetNumber;
    protected Sheet xlSheet;
    protected Row xlRow;

    private boolean applyBackgroundColor = true;
    private boolean applyVerticalTextConfiguration = false;

    public PoiExcelExporter(IOutputStreamProvider outputStreamProvider) {
        this.outputStreamProvider = outputStreamProvider;
    }

    @Override
    public OutputStream getOutputStream(Shell shell) {
        return outputStreamProvider.getOutputStream(shell);
    }

    @Override
    public void exportBegin(OutputStream outputStream) throws IOException {
        xlCellStyles = new HashMap<ExcelCellStyleAttributes, CellStyle>();
        xlWorkbook = createWorkbook();
    }

    @Override
    public void exportEnd(OutputStream outputStream) throws IOException {
        xlWorkbook.write(outputStream);

        xlCellStyles = null;
        xlWorkbook = null;
        sheetNumber = 0;
        xlSheet = null;
        xlRow = null;
    }

    @Override
    public void exportLayerBegin(OutputStream outputStream, String layerName)
            throws IOException {
        sheetNumber++;
        if (layerName == null || layerName.length() == 0) {
            layerName = "Sheet" + sheetNumber; //$NON-NLS-1$
        }
        xlSheet = xlWorkbook.createSheet(layerName);
    }

    @Override
    public void exportLayerEnd(OutputStream outputStream, String layerName)
            throws IOException {}

    @Override
    public void exportRowBegin(OutputStream outputStream, int rowPosition)
            throws IOException {
        xlRow = xlSheet.createRow(rowPosition);
    }

    @Override
    public void exportRowEnd(OutputStream outputStream, int rowPosition)
            throws IOException {}

    @Override
    public void exportCell(OutputStream outputStream,
            Object exportDisplayValue, ILayerCell cell,
            IConfigRegistry configRegistry) throws IOException {
        int columnPosition = cell.getColumnPosition();
        int rowPosition = cell.getRowPosition();

        if (columnPosition != cell.getOriginColumnPosition()
                || rowPosition != cell.getOriginRowPosition()) {
            return;
        }

        Cell xlCell = xlRow.createCell(columnPosition);

        int columnSpan = cell.getColumnSpan();
        int rowSpan = cell.getRowSpan();
        if (columnSpan > 1 || rowSpan > 1) {
            int lastRow = rowPosition + rowSpan - 1;
            int lastColumn = columnPosition + columnSpan - 1;
            xlSheet.addMergedRegion(new CellRangeAddress(rowPosition, lastRow,
                    columnPosition, lastColumn));
        }

        CellStyleProxy cellStyle = new CellStyleProxy(configRegistry,
                DisplayMode.NORMAL, cell.getConfigLabels().getLabels());
        Color fg = cellStyle
                .getAttributeValue(CellStyleAttributes.FOREGROUND_COLOR);
        Color bg = cellStyle
                .getAttributeValue(CellStyleAttributes.BACKGROUND_COLOR);
        org.eclipse.swt.graphics.Font font = cellStyle
                .getAttributeValue(CellStyleAttributes.FONT);
        FontData fontData = font.getFontData()[0];
        String dataFormat = null;

        int hAlign = HorizontalAlignmentEnum.getSWTStyle(cellStyle);
        int vAlign = VerticalAlignmentEnum.getSWTStyle(cellStyle);

        boolean vertical = this.applyVerticalTextConfiguration ? isVertical(configRegistry
                .getConfigAttribute(CellConfigAttributes.CELL_PAINTER,
                        DisplayMode.NORMAL, cell.getConfigLabels().getLabels()))
                : false;

        if (exportDisplayValue == null)
            exportDisplayValue = ""; //$NON-NLS-1$

        if (exportDisplayValue instanceof Boolean) {
            xlCell.setCellValue((Boolean) exportDisplayValue);
        } else if (exportDisplayValue instanceof Calendar) {
            dataFormat = getDataFormatString(cell, configRegistry);
            xlCell.setCellValue((Calendar) exportDisplayValue);
        } else if (exportDisplayValue instanceof Date) {
            dataFormat = getDataFormatString(cell, configRegistry);
            xlCell.setCellValue((Date) exportDisplayValue);
        } else if (exportDisplayValue instanceof Number) {
            xlCell.setCellValue(((Number) exportDisplayValue).doubleValue());
        } else {
            xlCell.setCellValue(exportDisplayValue.toString());
        }

        CellStyle xlCellStyle = getExcelCellStyle(fg, bg, fontData, dataFormat,
                hAlign, vAlign, vertical);
        xlCell.setCellStyle(xlCellStyle);
    }

    private boolean isVertical(ICellPainter cellPainter) {
        if (cellPainter instanceof VerticalTextPainter) {
            return true;
        } else if (cellPainter instanceof CellPainterWrapper) {
            return isVertical(((CellPainterWrapper) cellPainter)
                    .getWrappedPainter());
        } else if (cellPainter instanceof CellPainterDecorator) {
            return (isVertical(((CellPainterDecorator) cellPainter)
                    .getBaseCellPainter()) || isVertical(((CellPainterDecorator) cellPainter)
                    .getDecoratorCellPainter()));
        }
        return false;
    }

    private CellStyle getExcelCellStyle(Color fg, Color bg, FontData fontData,
            String dataFormat, int hAlign, int vAlign, boolean vertical) {

        CellStyle xlCellStyle = xlCellStyles.get(new ExcelCellStyleAttributes(
                fg, bg, fontData, dataFormat, hAlign, vAlign, vertical));

        if (xlCellStyle == null) {
            xlCellStyle = xlWorkbook.createCellStyle();

            if (applyBackgroundColor) {
                // Note: xl fill foreground = background
                setFillForegroundColor(xlCellStyle, bg);
                xlCellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
            }

            Font xlFont = xlWorkbook.createFont();
            setFontColor(xlFont, fg);
            xlFont.setFontName(fontData.getName());
            xlFont.setFontHeightInPoints((short) fontData.getHeight());
            xlCellStyle.setFont(xlFont);

            if (vertical)
                xlCellStyle.setRotation((short) 90);

            switch (hAlign) {
                case SWT.CENTER:
                    xlCellStyle.setAlignment(CellStyle.ALIGN_CENTER);
                    break;
                case SWT.LEFT:
                    xlCellStyle.setAlignment(CellStyle.ALIGN_LEFT);
                    break;
                case SWT.RIGHT:
                    xlCellStyle.setAlignment(CellStyle.ALIGN_RIGHT);
                    break;
            }
            switch (vAlign) {
                case SWT.TOP:
                    xlCellStyle.setVerticalAlignment(CellStyle.VERTICAL_TOP);
                    break;
                case SWT.CENTER:
                    xlCellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
                    break;
                case SWT.BOTTOM:
                    xlCellStyle.setVerticalAlignment(CellStyle.VERTICAL_BOTTOM);
                    break;
            }

            if (dataFormat != null) {
                CreationHelper createHelper = xlWorkbook.getCreationHelper();
                xlCellStyle.setDataFormat(createHelper.createDataFormat()
                        .getFormat(dataFormat));
            }

            xlCellStyles.put(new ExcelCellStyleAttributes(fg, bg, fontData,
                    dataFormat, hAlign, vAlign, vertical), xlCellStyle);
        }
        return xlCellStyle;
    }

    /**
     *
     * @param cell
     *            The cell for which the date format needs to be determined.
     * @param configRegistry
     *            The ConfigRegistry needed to retrieve the configuration.
     * @return The date format that should be used to format Date or Calendar
     *         values in the export.
     */
    protected String getDataFormatString(ILayerCell cell,
            IConfigRegistry configRegistry) {
        String dataFormat = configRegistry.getConfigAttribute(
                ExportConfigAttributes.DATE_FORMAT, DisplayMode.NORMAL, cell
                        .getConfigLabels().getLabels());
        if (dataFormat == null) {
            dataFormat = "m/d/yy h:mm"; //$NON-NLS-1$
        }
        return dataFormat;
    }

    /**
     *
     * @param applyBackgroundColor
     *            <code>true</code> to apply the background color set in the
     *            NatTable to the exported Excel. This also includes white
     *            background and header background color. <code>false</code> if
     *            the background color should not be set on export.
     */
    public void setApplyBackgroundColor(boolean applyBackgroundColor) {
        this.applyBackgroundColor = applyBackgroundColor;
    }

    /**
     * Configure this exporter whether it should check for vertical text
     * configuration in NatTable and apply the corresponding rotation style
     * attribute in the export, or not.
     * <p>
     * Note: As showing text vertically in NatTable is not a style information
     * but a configured via painter implementation, the check whether text is
     * showed vertically needs to be done via reflection. Therefore setting this
     * value to <code>true</code> could cause performance issues. As vertical
     * text is not the default case and the effect on performance might be
     * negative, the default value for this configuration is <code>false</code>.
     * If vertical text (e.g. column headers) should also be exported
     * vertically, you need to set this value to <code>true</code>.
     *
     * @param inspectVertical
     *            <code>true</code> to configure this exporter to check for
     *            vertical text configuration and apply the rotation style for
     *            the export, <code>false</code> to always use the regular text
     *            direction, regardless of vertical rendered text in NatTable.
     */
    public void setApplyVerticalTextConfiguration(boolean inspectVertical) {
        this.applyVerticalTextConfiguration = inspectVertical;
    }

    protected abstract Workbook createWorkbook();

    protected abstract void setFillForegroundColor(CellStyle xlCellStyle,
            Color swtColor);

    protected abstract void setFontColor(Font xlFont, Color swtColor);

    @Override
    public Object getResult() {
        return outputStreamProvider.getResult();
    }

}
TOP

Related Classes of org.eclipse.nebula.widgets.nattable.extension.poi.PoiExcelExporter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.