Java tutorial
/******************************************************************************* * 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(); } }