| /** |
| * Copyright 2011-2019 Jonathan Nash and others |
| * |
| * Licensed 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. |
| * |
| * Contributors: |
| * Jonathan Nash - initial implementation |
| * Compex Systemhaus GmbH - adaptions for OSBP |
| */ |
| package org.eclipse.osbp.xtext.table.common.export; |
| |
| import com.vaadin.data.Container; |
| import com.vaadin.data.Property; |
| import com.vaadin.data.util.ObjectProperty; |
| |
| import org.apache.poi.hssf.usermodel.HSSFFont; |
| import org.apache.poi.hssf.usermodel.HSSFWorkbook; |
| import org.apache.poi.hssf.util.HSSFColor; |
| import org.apache.poi.ss.usermodel.Cell; |
| import org.apache.poi.ss.usermodel.CellStyle; |
| import org.apache.poi.ss.usermodel.ClientAnchor; |
| import org.apache.poi.ss.usermodel.CreationHelper; |
| import org.apache.poi.ss.usermodel.DataFormat; |
| import org.apache.poi.ss.usermodel.Drawing; |
| import org.apache.poi.ss.usermodel.Font; |
| import org.apache.poi.ss.usermodel.FormulaEvaluator; |
| import org.apache.poi.ss.usermodel.IndexedColors; |
| import org.apache.poi.ss.usermodel.Picture; |
| import org.apache.poi.ss.usermodel.PrintSetup; |
| 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.apache.poi.ss.util.CellUtil; |
| import org.apache.poi.ss.util.RegionUtil; |
| import org.apache.poi.util.IOUtils; |
| import org.eclipse.osbp.ui.api.themes.IThemeResourceService; |
| import org.eclipse.osbp.ui.api.themes.IThemeResourceService.ThemeResourceType; |
| import org.eclipse.osbp.xtext.table.common.CellSetImage; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.tepi.filtertable.FilterTable; |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.math.BigDecimal; |
| import java.util.Collection; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| /** |
| * The Class ExcelExport. Implementation of TableExport to export Vaadin Tables to Excel .xls files. |
| * |
| * @author jnash |
| * @version $Revision: 1.2 $ |
| */ |
| public class ExcelExport extends TableExport { |
| |
| /** |
| * The Constant serialVersionUID. |
| */ |
| private static final long serialVersionUID = -8404407996727936497L; |
| private static final Logger LOGGER = LoggerFactory.getLogger(ExcelExport.class); |
| |
| /** |
| * The name of the sheet in the workbook the table contents will be written to. |
| */ |
| protected String sheetName; |
| |
| /** |
| * The title of the "report" of the table contents. |
| */ |
| protected String reportTitle; |
| |
| /** |
| * The filename of the workbook that will be sent to the user. |
| */ |
| protected String exportFileName; |
| |
| /** |
| * Flag indicating whether we will add a totals row to the FilterTable. A totals row in the FilterTable is |
| * typically implemented as a footer and therefore is not part of the data source. |
| */ |
| protected boolean displayTotals; |
| |
| /** |
| * Flag indicating whether the first column should be treated as row headers. They will then be |
| * formatted either like the column headers or a special row headers CellStyle can be specified. |
| */ |
| protected boolean rowHeaders = false; |
| |
| /** |
| * Flag indicating whether we should use table.formatPropertyValue() as the cell value instead |
| * of the property value using the specified data formats. |
| */ |
| protected boolean useTableFormatPropertyValue = false; |
| |
| /** |
| * The workbook that contains the sheet containing the report with the table contents. |
| */ |
| protected final transient Workbook workbook; |
| |
| /** |
| * The Sheet object that will contain the table contents report. |
| */ |
| protected transient Sheet sheet; |
| protected transient Sheet hierarchicalTotalsSheet = null; |
| |
| /** |
| * The POI cell creation helper. |
| */ |
| protected transient CreationHelper createHelper; |
| protected transient DataFormat dataFormat; |
| protected transient Drawing drawing; |
| |
| /** |
| * Various styles that are used in report generation. These can be set by the user if the |
| * default style is not desired to be used. |
| */ |
| protected transient CellStyle dateCellStyle; |
| protected transient CellStyle doubleCellStyle; |
| protected transient CellStyle integerCellStyle; |
| protected transient CellStyle totalsDoubleCellStyle; |
| protected transient CellStyle totalsIntegerCellStyle; |
| protected transient CellStyle columnHeaderCellStyle; |
| protected transient CellStyle titleCellStyle; |
| protected Short dateDataFormat; |
| protected Short doubleDataFormat; |
| protected Short integerDataFormat; |
| protected transient Map<Short, CellStyle> dataFormatCellStylesMap = new HashMap<>(); |
| |
| /** |
| * The default row header style is null and, if row headers are specified with |
| * setRowHeaders(true), then the column headers style is used. setRowHeaderStyle() allows the |
| * user to specify a different row header style. |
| */ |
| protected transient CellStyle rowHeaderCellStyle = null; |
| |
| /** |
| * The totals row. |
| */ |
| protected transient Row titleRow; |
| protected transient Row headerRow; |
| protected transient Row totalsRow; |
| protected transient Row hierarchicalTotalsRow; |
| // This let's the user specify the data format of the property in case the formatting of the property |
| // will not be properly identified by the class of the property. In this case, the specified format is |
| // used. However, all other cell stylings will be those of the |
| protected transient Map<Object, String> propertyExcelFormatMap = new HashMap<>(); |
| |
| /** |
| * At minimum, we need a FilterTable to export. Everything else has default settings. |
| * |
| * @param table the table |
| */ |
| public ExcelExport(final FilterTable table, IThemeResourceService themeResourceService) { |
| this(table, themeResourceService, null); |
| } |
| |
| /** |
| * Instantiates a new TableExport class. |
| * |
| * @param table the table |
| * @param sheetName the sheet name |
| */ |
| public ExcelExport(final FilterTable table, IThemeResourceService themeResourceService, final String sheetName) { |
| this(table, themeResourceService, sheetName, null); |
| } |
| |
| /** |
| * Instantiates a new TableExport class. |
| * |
| * @param table the table |
| * @param sheetName the sheet name |
| * @param reportTitle the report title |
| */ |
| public ExcelExport(final FilterTable table, IThemeResourceService themeResourceService, final String sheetName, final String reportTitle) { |
| this(table, themeResourceService, sheetName, reportTitle, null); |
| } |
| |
| /** |
| * Instantiates a new TableExport class. |
| * |
| * @param table the table |
| * @param sheetName the sheet name |
| * @param reportTitle the report title |
| * @param exportFileName the export file name |
| */ |
| public ExcelExport(final FilterTable table, IThemeResourceService themeResourceService, final String sheetName, final String reportTitle, |
| final String exportFileName) { |
| this(table, themeResourceService, sheetName, reportTitle, exportFileName, true); |
| } |
| |
| /** |
| * Instantiates a new TableExport class. This is the final constructor that all other |
| * constructors end up calling. If the other constructors were called then they pass in the |
| * default parameters. |
| * |
| * @param table the table |
| * @param sheetName the sheet name |
| * @param reportTitle the report title |
| * @param exportFileName the export file name |
| * @param hasTotalsRow flag indicating whether we should create a totals row |
| */ |
| public ExcelExport(final FilterTable table, IThemeResourceService themeResourceService, final String sheetName, final String reportTitle, |
| final String exportFileName, final boolean hasTotalsRow) { |
| this(table, themeResourceService, new HSSFWorkbook(), sheetName, reportTitle, exportFileName, hasTotalsRow); |
| } |
| |
| public ExcelExport(final FilterTable table, IThemeResourceService themeResourceService, final Workbook wkbk, final String shtName, final String rptTitle, |
| final String xptFileName, final boolean hasTotalsRow) { |
| super(table, themeResourceService); |
| workbook = wkbk; |
| init(shtName, rptTitle, xptFileName, hasTotalsRow); |
| format(); |
| } |
| |
| /** |
| * At minimum, we need a FilterTable to export. Everything else has default settings. |
| * |
| * @param tableHolder the tableHolder |
| */ |
| public ExcelExport(final TableHolder tableHolder) { |
| this(tableHolder, null); |
| } |
| |
| /** |
| * Instantiates a new TableExport class. |
| * |
| * @param tableHolder the tableHolder |
| * @param sheetName the sheet name |
| */ |
| public ExcelExport(final TableHolder tableHolder, final String sheetName) { |
| this(tableHolder, sheetName, null); |
| } |
| |
| /** |
| * Instantiates a new TableExport class. |
| * |
| * @param tableHolder the tableHolder |
| * @param sheetName the sheet name |
| * @param reportTitle the report title |
| */ |
| public ExcelExport(final TableHolder tableHolder, final String sheetName, final String reportTitle) { |
| this(tableHolder, sheetName, reportTitle, null); |
| } |
| |
| /** |
| * Instantiates a new TableExport class. |
| * |
| * @param tableHolder the tableHolder |
| * @param sheetName the sheet name |
| * @param reportTitle the report title |
| * @param exportFileName the export file name |
| */ |
| public ExcelExport(final TableHolder tableHolder, final String sheetName, final String reportTitle, |
| final String exportFileName) { |
| this(tableHolder, sheetName, reportTitle, exportFileName, true); |
| } |
| |
| /** |
| * Instantiates a new TableExport class. This is the final constructor that all other |
| * constructors end up calling. If the other constructors were called then they pass in the |
| * default parameters. |
| * |
| * @param tableHolder the tableHolder |
| * @param sheetName the sheet name |
| * @param reportTitle the report title |
| * @param exportFileName the export file name |
| * @param hasTotalsRow flag indicating whether we should create a totals row |
| */ |
| public ExcelExport(final TableHolder tableHolder, final String sheetName, final String reportTitle, |
| final String exportFileName, final boolean hasTotalsRow) { |
| this(tableHolder, new HSSFWorkbook(), sheetName, reportTitle, exportFileName, hasTotalsRow); |
| } |
| |
| public ExcelExport(final TableHolder tableHolder, final Workbook wkbk, final String shtName, |
| final String rptTitle, final String xptFileName, final boolean hasTotalsRow) { |
| super(tableHolder); |
| workbook = wkbk; |
| init(shtName, rptTitle, xptFileName, hasTotalsRow); |
| } |
| |
| private void init(final String shtName, final String rptTitle, final String xptFileName, |
| final boolean hasTotalsRow) { |
| if ((null == shtName) || ("".equals(shtName))) { |
| sheetName = "FilterTable Export"; |
| } else { |
| sheetName = shtName; |
| } |
| if (null == rptTitle) { |
| reportTitle = ""; |
| } else { |
| reportTitle = rptTitle; |
| } |
| if ((null == xptFileName) || ("".equals(xptFileName))) { |
| exportFileName = "FilterTable-Export.xls"; |
| } else { |
| exportFileName = xptFileName; |
| } |
| displayTotals = hasTotalsRow; |
| |
| sheet = workbook.createSheet(sheetName); |
| createHelper = workbook.getCreationHelper(); |
| dataFormat = workbook.createDataFormat(); |
| drawing = sheet.createDrawingPatriarch(); |
| |
| dateDataFormat = defaultDateDataFormat(); |
| doubleDataFormat = defaultDoubleDataFormat(); |
| integerDataFormat = defaultIntegerDataFormat(); |
| |
| doubleCellStyle = defaultDataCellStyle(workbook); |
| doubleCellStyle.setDataFormat(doubleDataFormat); |
| dataFormatCellStylesMap.put(doubleDataFormat, doubleCellStyle); |
| |
| integerCellStyle = defaultDataCellStyle(workbook); |
| integerCellStyle.setDataFormat(integerDataFormat); |
| dataFormatCellStylesMap.put(integerDataFormat, integerCellStyle); |
| |
| dateCellStyle = defaultDataCellStyle(workbook); |
| dateCellStyle.setDataFormat(dateDataFormat); |
| dataFormatCellStylesMap.put(dateDataFormat, dateCellStyle); |
| |
| totalsDoubleCellStyle = defaultTotalsDoubleCellStyle(workbook); |
| totalsIntegerCellStyle = defaultTotalsIntegerCellStyle(workbook); |
| columnHeaderCellStyle = defaultHeaderCellStyle(workbook); |
| titleCellStyle = defaultTitleCellStyle(workbook); |
| } |
| |
| /* |
| * Set a new table to be exported in another workbook tab / sheet. |
| */ |
| public void setNextTable(final FilterTable table, final String sheetName) { |
| setTable(table); |
| sheet = workbook.createSheet(sheetName); |
| } |
| |
| public void setNextTableHolder(final TableHolder tableHolder, final String sheetName) { |
| setTableHolder(tableHolder); |
| sheet = workbook.createSheet(sheetName); |
| } |
| |
| /* |
| * This will exclude columns from the export that are not visible due to them being collapsed. |
| * This should be called before convertTable() is called. |
| */ |
| public void excludeCollapsedColumns() { |
| final Iterator<Object> iterator = getPropIds().iterator(); |
| while (iterator.hasNext()) { |
| final Object propId = iterator.next(); |
| if (getTableHolder().isColumnCollapsed(propId)) { |
| iterator.remove(); |
| } |
| } |
| } |
| |
| /** |
| * Creates the workbook containing the exported table data, without exporting it to the user. |
| */ |
| @Override |
| public void convertTable() { |
| final int startRow; |
| // initial setup |
| initialSheetSetup(); |
| |
| // add title row |
| startRow = addTitleRow(); |
| int row = startRow; |
| |
| // add header row |
| addHeaderRow(row); |
| row++; |
| |
| // add data rows |
| if (isHierarchical()) { |
| row = addHierarchicalDataRows(sheet, row); |
| } else { |
| row = addDataRows(sheet, row); |
| } |
| |
| // add totals row |
| if (displayTotals) { |
| addTotalsRow(row, startRow); |
| } |
| |
| // final sheet format before export |
| finalSheetFormat(); |
| } |
| |
| /** |
| * Export the workbook to the end-user. |
| * <p/> |
| * Code obtained from: http://vaadin.com/forum/-/message_boards/view_message/159583 |
| * |
| * @return true, if successful |
| */ |
| @Override |
| public boolean sendConverted() { |
| File tempFile = null; |
| FileOutputStream fileOut = null; |
| try { |
| tempFile = File.createTempFile("tmp", ".xls"); |
| fileOut = new FileOutputStream(tempFile); |
| workbook.write(fileOut); |
| if (null == mimeType) { |
| setMimeType(EXCEL_MIME_TYPE); |
| } |
| return super.sendConvertedFileToUser(getTableHolder().getUI(), tempFile, getReportTitle()+".xls"); |
| } catch (final IOException e) { |
| LOGGER.error("Converting to XLS failed with IOException {}", e); |
| return false; |
| } finally { |
| if(tempFile != null) { |
| tempFile.deleteOnExit(); |
| } |
| try { |
| if(fileOut != null) { |
| fileOut.close(); |
| } |
| } catch (final IOException e) { |
| // nothing to do |
| } |
| } |
| } |
| |
| /** |
| * Initial sheet setup. Override this method to specifically change initial, sheet-wide, |
| * settings. |
| */ |
| protected void initialSheetSetup() { |
| final PrintSetup printSetup = sheet.getPrintSetup(); |
| printSetup.setLandscape(true); |
| sheet.setFitToPage(true); |
| sheet.setHorizontallyCenter(true); |
| if ((isHierarchical()) && (displayTotals)) { |
| hierarchicalTotalsSheet = workbook.createSheet("tempHts"); |
| } |
| } |
| |
| /** |
| * Adds the title row. Override this method to change title-related aspects of the workbook. |
| * Alternately, the title Row Object is accessible via getTitleRow() after report creation. To |
| * change title text use setReportTitle(). To change title CellStyle use setTitleStyle(). |
| * |
| * @return the int |
| */ |
| protected int addTitleRow() { |
| if ((null == reportTitle) || ("".equals(reportTitle))) { |
| return 0; |
| } |
| titleRow = sheet.createRow(0); |
| titleRow.setHeightInPoints(45); |
| final Cell titleCell; |
| final CellRangeAddress cra; |
| if (rowHeaders) { |
| titleCell = titleRow.createCell(1); |
| cra = new CellRangeAddress(0, 0, 1, getPropIds().size() - 1); |
| sheet.addMergedRegion(cra); |
| } else { |
| titleCell = titleRow.createCell(0); |
| cra = new CellRangeAddress(0, 0, 0, getPropIds().size() - 1); |
| sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, getPropIds().size() - 1)); |
| } |
| titleCell.setCellValue(reportTitle); |
| titleCell.setCellStyle(titleCellStyle); |
| // cell borders don't work on merged ranges so, if there are borders |
| // we apply them to the merged range here. |
| if (titleCellStyle.getBorderLeft() != CellStyle.BORDER_NONE) { |
| RegionUtil.setBorderLeft(titleCellStyle.getBorderLeft(), cra, sheet, workbook); |
| } |
| if (titleCellStyle.getBorderRight() != CellStyle.BORDER_NONE) { |
| RegionUtil.setBorderRight(titleCellStyle.getBorderRight(), cra, sheet, workbook); |
| } |
| if (titleCellStyle.getBorderTop() != CellStyle.BORDER_NONE) { |
| RegionUtil.setBorderTop(titleCellStyle.getBorderTop(), cra, sheet, workbook); |
| } |
| if (titleCellStyle.getBorderBottom() != CellStyle.BORDER_NONE) { |
| RegionUtil.setBorderBottom(titleCellStyle.getBorderBottom(), cra, sheet, workbook); |
| } |
| return 1; |
| } |
| |
| /** |
| * Adds the header row. Override this method to change header-row-related aspects of the |
| * workbook. Alternately, the header Row Object is accessible via getHeaderRow() after report |
| * creation. To change header CellStyle, though, use setHeaderStyle(). |
| * |
| * @param row the row |
| */ |
| protected void addHeaderRow(final int row) { |
| headerRow = sheet.createRow(row); |
| Cell headerCell; |
| Object propId; |
| headerRow.setHeightInPoints(40); |
| for (int col = 0; col < getPropIds().size(); col++) { |
| propId = getPropIds().get(col); |
| headerCell = headerRow.createCell(col); |
| headerCell.setCellValue(createHelper.createRichTextString(getTableHolder().getColumnHeader(propId))); |
| headerCell.setCellStyle(getColumnHeaderStyle(row, col)); |
| |
| final Short poiAlignment = getTableHolder().getCellAlignment(propId); |
| CellUtil.setAlignment(headerCell, workbook, poiAlignment); |
| } |
| } |
| |
| /** |
| * This method is called by addTotalsRow() to determine what CellStyle to use. By default we |
| * just return totalsCellStyle which is either set to the default totals style, or can be |
| * overriden by the user using setTotalsStyle(). However, if the user wants to have different |
| * total items have different styles, then this method should be overriden. The parameters |
| * passed in are all potentially relevant items that may be used to determine what formatting to |
| * return, that are not accessible globally. |
| * |
| * @param row the row |
| * @param col the current column |
| * @return the header style |
| */ |
| protected CellStyle getColumnHeaderStyle(final int row, final int col) { |
| if ((rowHeaders) && (col == 0)) { |
| return titleCellStyle; |
| } |
| return columnHeaderCellStyle; |
| } |
| |
| /** |
| * For Hierarchical Containers, this method recursively adds root items and child items. The |
| * child items are appropriately grouped using grouping/outlining sheet functionality. Override |
| * this method to make any changes. To change the CellStyle used for all FilterTable data use |
| * setDataStyle(). For different data cells to have different CellStyles, override |
| * getDataStyle(). |
| * |
| * @param row the row |
| * @return the int |
| */ |
| protected int addHierarchicalDataRows(final Sheet sheetToAddTo, final int row) { |
| final Collection<?> roots; |
| int localRow = row; |
| roots = ((Container.Hierarchical) getTableHolder().getContainerDataSource()).rootItemIds(); |
| /* |
| * For Hierarchical Containers, the outlining/grouping in the sheet is with the summary row |
| * at the top and the grouped/outlined subcategories below. |
| */ |
| sheet.setRowSumsBelow(false); |
| int count = 0; |
| for (final Object rootId : roots) { |
| count = addDataRowRecursively(sheetToAddTo, rootId, localRow); |
| // for totals purposes, we just want to add rootIds which contain totals |
| // so we store just the totals in a separate sheet. |
| if (displayTotals) { |
| addDataRow(hierarchicalTotalsSheet, rootId, localRow); |
| } |
| if (count > 1) { |
| sheet.groupRow(localRow + 1, (localRow + count) - 1); |
| sheet.setRowGroupCollapsed(localRow + 1, true); |
| } |
| localRow = localRow + count; |
| } |
| return localRow; |
| } |
| |
| /** |
| * this method adds row items for non-Hierarchical Containers. Override this method to make any |
| * changes. To change the CellStyle used for all FilterTable data use setDataStyle(). For different |
| * data cells to have different CellStyles, override getDataStyle(). |
| * |
| * @param row the row |
| * @return the int |
| */ |
| protected int addDataRows(final Sheet sheetToAddTo, final int row) { |
| final Collection<?> itemIds = getTableHolder().getContainerDataSource().getItemIds(); |
| int localRow = row; |
| int count = 0; |
| for (final Object itemId : itemIds) { |
| addDataRow(sheetToAddTo, itemId, localRow); |
| count = 1; |
| if (count > 1) { |
| sheet.groupRow(localRow + 1, (localRow + count) - 1); |
| sheet.setRowGroupCollapsed(localRow + 1, true); |
| } |
| localRow = localRow + count; |
| } |
| return localRow; |
| } |
| |
| /** |
| * Used by addHierarchicalDataRows() to implement the recursive calls. |
| * |
| * @param rootItemId the root item id |
| * @param row the row |
| * @return the int |
| */ |
| private int addDataRowRecursively(final Sheet sheetToAddTo, final Object rootItemId, final int row) { |
| int numberAdded = 0; |
| int localRow = row; |
| addDataRow(sheetToAddTo, rootItemId, row); |
| numberAdded++; |
| if (((Container.Hierarchical) getTableHolder().getContainerDataSource()).hasChildren(rootItemId)) { |
| final Collection<?> children = ((Container.Hierarchical) getTableHolder().getContainerDataSource()) |
| .getChildren(rootItemId); |
| for (final Object child : children) { |
| localRow++; |
| numberAdded = numberAdded + addDataRowRecursively(sheetToAddTo, child, localRow); |
| } |
| } |
| return numberAdded; |
| } |
| |
| /** |
| * This method is ultimately used by either addDataRows() or addHierarchicalDataRows() to |
| * actually add the data to the Sheet. |
| * |
| * @param rootItemId the root item id |
| * @param row the row |
| */ |
| |
| protected void addDataRow(final Sheet sheetToAddTo, final Object rootItemId, final int row) { |
| final Row sheetRow = sheetToAddTo.createRow(row); |
| Property<?> prop; |
| Object propId; |
| Object value; |
| Cell sheetCell; |
| for (int col = 0; col < getPropIds().size(); col++) { |
| propId = getPropIds().get(col); |
| prop = getProperty(rootItemId, propId); |
| if (null == prop) { |
| value = null; |
| } else { |
| value = prop.getValue(); |
| } |
| sheetCell = sheetRow.createCell(col); |
| final CellStyle cs = getCellStyle(rootItemId, row, col, false); |
| sheetCell.setCellStyle(cs); |
| final Short poiAlignment = getTableHolder().getCellAlignment(propId); |
| CellUtil.setAlignment(sheetCell, workbook, poiAlignment); |
| if (null != value) { |
| if (!isNumeric(prop.getType())) { |
| if (java.util.Date.class.isAssignableFrom(prop.getType())) { |
| sheetCell.setCellValue((Date) value); |
| } else if(CellSetImage.class.isAssignableFrom(prop.getType())) { |
| ClientAnchor anchor = createHelper.createClientAnchor(); |
| anchor.setAnchorType( ClientAnchor.MOVE_AND_RESIZE ); |
| InputStream stream = getThemeResourceService().getThemeResourceInputStream(((CellSetImage)prop.getValue()).getResourceName(), ThemeResourceType.ICON); |
| try { |
| int pictureIndex = workbook.addPicture(IOUtils.toByteArray(stream), Workbook.PICTURE_TYPE_PNG); |
| anchor.setCol1( col ); |
| anchor.setRow1( row ); |
| anchor.setRow2( row ); |
| anchor.setCol2( col+1 ); |
| final Picture pict = drawing.createPicture( anchor, pictureIndex ); |
| pict.resize(); |
| } catch (IOException e) { |
| LOGGER.error("{}", e); |
| } |
| |
| } else { |
| sheetCell.setCellValue(createHelper.createRichTextString(value.toString())); |
| } |
| } else { |
| try { |
| // parse all numbers as double, the format will determine how they appear |
| final Double d = Double.parseDouble(value.toString()); |
| sheetCell.setCellValue(d); |
| } catch (final NumberFormatException nfe) { |
| LOGGER.error("NumberFormatException parsing a numeric value: {}", nfe); |
| sheetCell.setCellValue(createHelper.createRichTextString(value.toString())); |
| } |
| } |
| } |
| } |
| } |
| |
| private Property<?> getProperty(final Object rootItemId, final Object propId) { |
| Property<?> prop; |
| if (getTableHolder().isGeneratedColumn(propId)) { |
| prop = getTableHolder().getPropertyForGeneratedColumn(propId, rootItemId); |
| } else { |
| prop = getTableHolder().getContainerDataSource().getContainerProperty(rootItemId, propId); |
| if (useTableFormatPropertyValue) { |
| if (getTableHolder().isExportableFormattedProperty()) { |
| final String formattedProp = getTableHolder().getFormattedPropertyValue(rootItemId, propId, prop); |
| if (null == prop) { |
| prop = new ObjectProperty<>(formattedProp, String.class); |
| } else { |
| final Object val = prop.getValue(); |
| if (null == val) { |
| prop = new ObjectProperty<>(formattedProp, String.class); |
| } else { |
| if (!val.toString().equals(formattedProp)) { |
| prop = new ObjectProperty<>(formattedProp, String.class); |
| } |
| } |
| } |
| } else { |
| LOGGER.error("{}", "Cannot use FilterTable formatted property unless FilterTable is instance of ExportableFormattedProperty"); |
| } |
| } |
| } |
| return prop; |
| } |
| |
| private Class<?> getPropertyType(final Object propId) { |
| Class<?> classType; |
| if (getTableHolder().isGeneratedColumn(propId)) { |
| classType = getTableHolder().getPropertyTypeForGeneratedColumn(propId); |
| } else { |
| classType = getTableHolder().getContainerDataSource().getType(propId); |
| } |
| return classType; |
| } |
| |
| public void setExcelFormatOfProperty(final Object propertyId, final String excelFormat) { |
| if (propertyExcelFormatMap.containsKey(propertyId)) { |
| propertyExcelFormatMap.remove(propertyId); |
| } |
| propertyExcelFormatMap.put(propertyId.toString(), excelFormat); |
| } |
| |
| /** |
| * This method is called by addDataRow() to determine what CellStyle to use. By default we just |
| * return dataStyle which is either set to the default data style, or can be overriden by the |
| * user using setDataStyle(). However, if the user wants to have different data items have |
| * different styles, then this method should be overriden. The parameters passed in are all |
| * potentially relevant items that may be used to determine what formatting to return, that are |
| * not accessible globally. |
| * |
| * @param rootItemId the root item id |
| * @param row the row |
| * @param col the col |
| * @return the data style |
| */ |
| protected CellStyle getCellStyle(final Object rootItemId, final int row, final int col, final boolean totalsRow) { |
| final Object propId = getPropIds().get(col); |
| // get the basic style for the type of cell (i.e. data, header, total) |
| if ((rowHeaders) && (col == 0)) { |
| if (null == rowHeaderCellStyle) { |
| return columnHeaderCellStyle; |
| } |
| return rowHeaderCellStyle; |
| } |
| final Class<?> propType = getPropertyType(propId); |
| if (totalsRow) { |
| if (propertyExcelFormatMap.containsKey(propId)) { |
| final short df = dataFormat.getFormat(propertyExcelFormatMap.get(propId)); |
| final CellStyle customTotalStyle = workbook.createCellStyle(); |
| customTotalStyle.cloneStyleFrom(totalsDoubleCellStyle); |
| customTotalStyle.setDataFormat(df); |
| return customTotalStyle; |
| } |
| if (isIntegerLongShortOrBigDecimal(propType)) { |
| return totalsIntegerCellStyle; |
| } |
| return totalsDoubleCellStyle; |
| } |
| // Check if the user has over-ridden that data format of this property |
| if (propertyExcelFormatMap.containsKey(propId)) { |
| final short df = dataFormat.getFormat(propertyExcelFormatMap.get(propId)); |
| if (dataFormatCellStylesMap.containsKey(df)) { |
| return dataFormatCellStylesMap.get(df); |
| } |
| // if it hasn't already been created for re-use, we create a cell style and override the data format |
| // For data cells, each data format corresponds to a single complete cell style |
| final CellStyle retStyle = workbook.createCellStyle(); |
| retStyle.cloneStyleFrom(dataFormatCellStylesMap.get(doubleDataFormat)); |
| retStyle.setDataFormat(df); |
| dataFormatCellStylesMap.put(df, retStyle); |
| return retStyle; |
| } |
| // if not over-ridden, use the overall setting |
| if (isDoubleOrFloat(propType)) { |
| return dataFormatCellStylesMap.get(doubleDataFormat); |
| } else { |
| if (isIntegerLongShortOrBigDecimal(propType)) { |
| return dataFormatCellStylesMap.get(integerDataFormat); |
| } else { |
| if (java.util.Date.class.isAssignableFrom(propType)) { |
| return dataFormatCellStylesMap.get(dateDataFormat); |
| } |
| } |
| } |
| return dataFormatCellStylesMap.get(doubleDataFormat); |
| } |
| |
| /** |
| * Adds the totals row to the report. Override this method to make any changes. Alternately, the |
| * totals Row Object is accessible via getTotalsRow() after report creation. To change the |
| * CellStyle used for the totals row, use setFormulaStyle. For different totals cells to have |
| * different CellStyles, override getTotalsStyle(). |
| * |
| * @param currentRow the current row |
| * @param startRow the start row |
| */ |
| protected void addTotalsRow(final int currentRow, final int startRow) { |
| totalsRow = sheet.createRow(currentRow); |
| totalsRow.setHeightInPoints(30); |
| Cell cell; |
| CellRangeAddress cra; |
| for (int col = 0; col < getPropIds().size(); col++) { |
| final Object propId = getPropIds().get(col); |
| cell = totalsRow.createCell(col); |
| cell.setCellStyle(getCellStyle(currentRow, startRow, col, true)); |
| final Short poiAlignment = getTableHolder().getCellAlignment(propId); |
| CellUtil.setAlignment(cell, workbook, poiAlignment); |
| final Class<?> propType = getPropertyType(propId); |
| if (isNumeric(propType)) { |
| cra = new CellRangeAddress(startRow, currentRow - 1, col, col); |
| if (isHierarchical()) { |
| // 9 & 109 are for sum. 9 means include hidden cells, 109 means exclude. |
| // this will show the wrong value if the user expands an outlined category, so |
| // we will range value it first |
| cell.setCellFormula("SUM(" + cra.formatAsString(hierarchicalTotalsSheet.getSheetName(), |
| true) + ")"); |
| } else { |
| cell.setCellFormula("SUM(" + cra.formatAsString() + ")"); |
| } |
| } else { |
| if (0 == col) { |
| cell.setCellValue(createHelper.createRichTextString("Total")); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Final formatting of the sheet upon completion of writing the data. For example, we can only |
| * size the column widths once the data is in the report and the sheet knows how wide the data |
| * is. |
| */ |
| protected void finalSheetFormat() { |
| final FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); |
| if (isHierarchical()) { |
| /* |
| * evaluateInCell() is equivalent to paste special -> value. The formula refers to cells |
| * in the other sheet we are going to delete. We sum in the other sheet because if we |
| * summed in the main sheet, we would double count. Subtotal with hidden rows is not yet |
| * implemented in POI. |
| */ |
| for (final Row r : sheet) { |
| for (final Cell c : r) { |
| if (c.getCellType() == Cell.CELL_TYPE_FORMULA) { |
| evaluator.evaluateInCell(c); |
| } |
| } |
| } |
| workbook.setActiveSheet(workbook.getSheetIndex(sheet)); |
| if (hierarchicalTotalsSheet != null) { |
| workbook.removeSheetAt(workbook.getSheetIndex(hierarchicalTotalsSheet)); |
| } |
| } else { |
| evaluator.evaluateAll(); |
| } |
| for (int col = 0; col < getPropIds().size(); col++) { |
| sheet.autoSizeColumn(col); |
| } |
| } |
| |
| /** |
| * Returns the default title style. Obtained from: http://svn.apache.org/repos/asf/poi |
| * /trunk/src/examples/src/org/apache/poi/ss/examples/TimesheetDemo.java |
| * |
| * @param wb the wb |
| * @return the cell style |
| */ |
| protected CellStyle defaultTitleCellStyle(final Workbook wb) { |
| CellStyle style; |
| final Font titleFont = wb.createFont(); |
| titleFont.setFontHeightInPoints((short) 18); |
| titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD); |
| style = wb.createCellStyle(); |
| style.setAlignment(CellStyle.ALIGN_CENTER); |
| style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); |
| style.setFont(titleFont); |
| return style; |
| } |
| |
| /** |
| * Returns the default header style. Obtained from: http://svn.apache.org/repos/asf/poi |
| * /trunk/src/examples/src/org/apache/poi/ss/examples/TimesheetDemo.java |
| * |
| * @param wb the wb |
| * @return the cell style |
| */ |
| protected CellStyle defaultHeaderCellStyle(final Workbook wb) { |
| CellStyle style; |
| final Font monthFont = wb.createFont(); |
| monthFont.setFontHeightInPoints((short) 11); |
| monthFont.setColor(IndexedColors.WHITE.getIndex()); |
| style = wb.createCellStyle(); |
| style.setAlignment(CellStyle.ALIGN_CENTER); |
| style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); |
| style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); |
| style.setFillPattern(CellStyle.SOLID_FOREGROUND); |
| style.setFont(monthFont); |
| style.setWrapText(true); |
| return style; |
| } |
| |
| /** |
| * Returns the default data cell style. Obtained from: http://svn.apache.org/repos/asf/poi |
| * /trunk/src/examples/src/org/apache/poi/ss/examples/TimesheetDemo.java |
| * |
| * @param wb the wb |
| * @return the cell style |
| */ |
| protected CellStyle defaultDataCellStyle(final Workbook wb) { |
| CellStyle style; |
| style = wb.createCellStyle(); |
| style.setAlignment(CellStyle.ALIGN_CENTER); |
| style.setWrapText(true); |
| style.setBorderRight(CellStyle.BORDER_THIN); |
| style.setRightBorderColor(IndexedColors.BLACK.getIndex()); |
| style.setBorderLeft(CellStyle.BORDER_THIN); |
| style.setLeftBorderColor(IndexedColors.BLACK.getIndex()); |
| style.setBorderTop(CellStyle.BORDER_THIN); |
| style.setTopBorderColor(IndexedColors.BLACK.getIndex()); |
| style.setBorderBottom(CellStyle.BORDER_THIN); |
| style.setBottomBorderColor(IndexedColors.BLACK.getIndex()); |
| style.setDataFormat(doubleDataFormat); |
| return style; |
| } |
| |
| /** |
| * Returns the default totals row style for Double data. Obtained from: http://svn.apache.org/repos/asf/poi |
| * /trunk/src/examples/src/org/apache/poi/ss/examples/TimesheetDemo.java |
| * |
| * @param wb the wb |
| * @return the cell style |
| */ |
| protected CellStyle defaultTotalsDoubleCellStyle(final Workbook wb) { |
| CellStyle style; |
| style = wb.createCellStyle(); |
| style.setAlignment(CellStyle.ALIGN_CENTER); |
| style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); |
| style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); |
| style.setFillPattern(CellStyle.SOLID_FOREGROUND); |
| style.setDataFormat(doubleDataFormat); |
| return style; |
| } |
| |
| /** |
| * Returns the default totals row style for Integer data. Obtained from: http://svn.apache.org/repos/asf/poi |
| * /trunk/src/examples/src/org/apache/poi/ss/examples/TimesheetDemo.java |
| * |
| * @param wb the wb |
| * @return the cell style |
| */ |
| protected CellStyle defaultTotalsIntegerCellStyle(final Workbook wb) { |
| CellStyle style; |
| style = wb.createCellStyle(); |
| style.setAlignment(CellStyle.ALIGN_CENTER); |
| style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); |
| style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); |
| style.setFillPattern(CellStyle.SOLID_FOREGROUND); |
| style.setDataFormat(integerDataFormat); |
| return style; |
| } |
| |
| protected short defaultDoubleDataFormat() { |
| return createHelper.createDataFormat().getFormat("0.00"); |
| } |
| |
| protected short defaultIntegerDataFormat() { |
| return createHelper.createDataFormat().getFormat("0"); |
| } |
| |
| protected short defaultDateDataFormat() { |
| return createHelper.createDataFormat().getFormat("mm/dd/yyyy"); |
| } |
| |
| public void setDoubleDataFormat(final String excelDoubleFormat) { |
| CellStyle prevDoubleDataStyle = null; |
| if (dataFormatCellStylesMap.containsKey(doubleDataFormat)) { |
| prevDoubleDataStyle = dataFormatCellStylesMap.get(doubleDataFormat); |
| dataFormatCellStylesMap.remove(doubleDataFormat); |
| } |
| doubleDataFormat = createHelper.createDataFormat().getFormat(excelDoubleFormat); |
| if (null != prevDoubleDataStyle) { |
| doubleCellStyle = prevDoubleDataStyle; |
| doubleCellStyle.setDataFormat(doubleDataFormat); |
| dataFormatCellStylesMap.put(doubleDataFormat, doubleCellStyle); |
| } |
| } |
| |
| public void setIntegerDataFormat(final String excelIntegerFormat) { |
| CellStyle prevIntegerDataStyle = null; |
| if (dataFormatCellStylesMap.containsKey(integerDataFormat)) { |
| prevIntegerDataStyle = dataFormatCellStylesMap.get(integerDataFormat); |
| dataFormatCellStylesMap.remove(integerDataFormat); |
| } |
| integerDataFormat = createHelper.createDataFormat().getFormat(excelIntegerFormat); |
| if (null != prevIntegerDataStyle) { |
| integerCellStyle = prevIntegerDataStyle; |
| integerCellStyle.setDataFormat(integerDataFormat); |
| dataFormatCellStylesMap.put(integerDataFormat, integerCellStyle); |
| } |
| } |
| |
| public void setDateDataFormat(final String excelDateFormat) { |
| CellStyle prevDateDataStyle = null; |
| if (dataFormatCellStylesMap.containsKey(dateDataFormat)) { |
| prevDateDataStyle = dataFormatCellStylesMap.get(dateDataFormat); |
| dataFormatCellStylesMap.remove(dateDataFormat); |
| } |
| dateDataFormat = createHelper.createDataFormat().getFormat(excelDateFormat); |
| if (null != prevDateDataStyle) { |
| dateCellStyle = prevDateDataStyle; |
| dateCellStyle.setDataFormat(dateDataFormat); |
| dataFormatCellStylesMap.put(dateDataFormat, dateCellStyle); |
| } |
| } |
| |
| /** |
| * Utility method to determine whether value being put in the Cell is numeric. |
| * |
| * @param type the type |
| * @return true, if is numeric |
| */ |
| private boolean isNumeric(final Class<?> type) { |
| if (isIntegerLongShortOrBigDecimal(type)) { |
| return true; |
| } |
| return isDoubleOrFloat(type); |
| } |
| |
| /** |
| * Utility method to determine whether value being put in the Cell is integer-like type. |
| * |
| * @param type the type |
| * @return true, if is integer-like |
| */ |
| private boolean isIntegerLongShortOrBigDecimal(final Class<?> type) { |
| if ((Integer.class.equals(type) || (int.class.equals(type)))) { |
| return true; |
| } |
| if ((Long.class.equals(type) || (long.class.equals(type)))) { |
| return true; |
| } |
| if ((Short.class.equals(type)) || (short.class.equals(type))) { |
| return true; |
| } |
| return BigDecimal.class.equals(type); |
| } |
| |
| /** |
| * Utility method to determine whether value being put in the Cell is double-like type. |
| * |
| * @param type the type |
| * @return true, if is double-like |
| */ |
| private boolean isDoubleOrFloat(final Class<?> type) { |
| if ((Double.class.equals(type)) || (double.class.equals(type))) { |
| return true; |
| } |
| return ((Float.class.equals(type)) || (float.class.equals(type))); |
| } |
| |
| /** |
| * Gets the workbook. |
| * |
| * @return the workbook |
| */ |
| public Workbook getWorkbook() { |
| return workbook; |
| } |
| |
| /** |
| * Gets the sheet name. |
| * |
| * @return the sheet name |
| */ |
| public String getSheetName() { |
| return sheetName; |
| } |
| |
| /** |
| * Gets the report title. |
| * |
| * @return the report title |
| */ |
| public String getReportTitle() { |
| return reportTitle; |
| } |
| |
| /** |
| * Gets the export file name. |
| * |
| * @return the export file name |
| */ |
| public String getExportFileName() { |
| return exportFileName; |
| } |
| |
| /** |
| * Gets the cell style used for report data.. |
| * |
| * @return the cell style |
| */ |
| public CellStyle getDoubleDataStyle() { |
| return doubleCellStyle; |
| } |
| |
| /** |
| * Gets the cell style used for report data.. |
| * |
| * @return the cell style |
| */ |
| public CellStyle getIntegerDataStyle() { |
| return integerCellStyle; |
| } |
| |
| public CellStyle getDateDataStyle() { |
| return dateCellStyle; |
| } |
| |
| /** |
| * Gets the cell style used for the report headers. |
| * |
| * @return the column header style |
| */ |
| public CellStyle getColumnHeaderStyle() { |
| return columnHeaderCellStyle; |
| } |
| |
| /** |
| * Gets the cell title used for the report title. |
| * |
| * @return the title style |
| */ |
| public CellStyle getTitleStyle() { |
| return titleCellStyle; |
| } |
| |
| /** |
| * Sets the text used for the report title. |
| * |
| * @param reportTitle the new report title |
| */ |
| public void setReportTitle(final String reportTitle) { |
| this.reportTitle = reportTitle; |
| } |
| |
| /** |
| * Sets the export file name. |
| * |
| * @param exportFileName the new export file name |
| */ |
| public void setExportFileName(final String exportFileName) { |
| this.exportFileName = exportFileName; |
| } |
| |
| /** |
| * Sets the cell style used for report data. |
| * |
| * @param doubleDataStyle the new data style |
| */ |
| public void setDoubleDataStyle(final CellStyle doubleDataStyle) { |
| this.doubleCellStyle = doubleDataStyle; |
| } |
| |
| /** |
| * Sets the cell style used for report data. |
| * |
| * @param integerDataStyle the new data style |
| */ |
| public void setIntegerDataStyle(final CellStyle integerDataStyle) { |
| this.integerCellStyle = integerDataStyle; |
| } |
| |
| /** |
| * Sets the cell style used for report data. |
| * |
| * @param dateDataStyle the new data style |
| */ |
| public void setDateDataStyle(final CellStyle dateDataStyle) { |
| this.dateCellStyle = dateDataStyle; |
| } |
| |
| /** |
| * Sets the cell style used for the report headers. |
| * |
| * @param columnHeaderStyle CellStyle |
| */ |
| public void setColumnHeaderStyle(final CellStyle columnHeaderStyle) { |
| this.columnHeaderCellStyle = columnHeaderStyle; |
| } |
| |
| /** |
| * Sets the cell style used for the report title. |
| * |
| * @param titleStyle the new title style |
| */ |
| public void setTitleStyle(final CellStyle titleStyle) { |
| this.titleCellStyle = titleStyle; |
| } |
| |
| /** |
| * Gets the title row. |
| * |
| * @return the title row |
| */ |
| public Row getTitleRow() { |
| return titleRow; |
| } |
| |
| /** |
| * Gets the header row. |
| * |
| * @return the header row |
| */ |
| public Row getHeaderRow() { |
| return headerRow; |
| } |
| |
| /** |
| * Gets the totals row. |
| * |
| * @return the totals row |
| */ |
| public Row getTotalsRow() { |
| return totalsRow; |
| } |
| |
| /** |
| * Gets the cell style used for the totals row. |
| * |
| * @return the totals style |
| */ |
| public CellStyle getTotalsDoubleStyle() { |
| return totalsDoubleCellStyle; |
| } |
| |
| /** |
| * Sets the cell style used for the totals row. |
| * |
| * @param totalsDoubleStyle the new totals style |
| */ |
| public void setTotalsDoubleStyle(final CellStyle totalsDoubleStyle) { |
| this.totalsDoubleCellStyle = totalsDoubleStyle; |
| } |
| |
| /** |
| * Gets the cell style used for the totals row. |
| * |
| * @return the totals style |
| */ |
| public CellStyle getTotalsIntegerStyle() { |
| return totalsIntegerCellStyle; |
| } |
| |
| /** |
| * Sets the cell style used for the totals row. |
| * |
| * @param totalsIntegerStyle the new totals style |
| */ |
| public void setTotalsIntegerStyle(final CellStyle totalsIntegerStyle) { |
| this.totalsIntegerCellStyle = totalsIntegerStyle; |
| } |
| |
| /** |
| * Flag indicating whether a totals row will be added to the report or not. |
| * |
| * @return true, if totals row will be added |
| */ |
| public boolean isDisplayTotals() { |
| return displayTotals; |
| } |
| |
| /** |
| * Sets the flag indicating whether a totals row will be added to the report or not. |
| * |
| * @param displayTotals boolean |
| */ |
| public void setDisplayTotals(final boolean displayTotals) { |
| this.displayTotals = displayTotals; |
| } |
| |
| public void setUseTableFormatPropertyValue(final boolean useFormatPropertyValue) { |
| this.useTableFormatPropertyValue = useFormatPropertyValue; |
| } |
| |
| /** |
| * See value of flag indicating whether the first column should be treated as row headers. |
| * |
| * @return boolean |
| */ |
| public boolean hasRowHeaders() { |
| return rowHeaders; |
| } |
| |
| /** |
| * Method getRowHeaderStyle. |
| * |
| * @return CellStyle |
| */ |
| public CellStyle getRowHeaderStyle() { |
| return rowHeaderCellStyle; |
| } |
| |
| /** |
| * Set value of flag indicating whether the first column should be treated as row headers. |
| * |
| * @param rowHeaders boolean |
| */ |
| public void setRowHeaders(final boolean rowHeaders) { |
| this.rowHeaders = rowHeaders; |
| } |
| |
| /** |
| * Method setRowHeaderStyle. |
| * |
| * @param rowHeaderStyle CellStyle |
| */ |
| public void setRowHeaderStyle(final CellStyle rowHeaderStyle) { |
| this.rowHeaderCellStyle = rowHeaderStyle; |
| } |
| |
| private void format() { |
| setRowHeaders(true); |
| CellStyle style; |
| |
| style = getTitleStyle(); |
| setStyle(style, HSSFColor.DARK_BLUE.index, 18, HSSFColor.WHITE.index, true, |
| CellStyle.ALIGN_CENTER_SELECTION); |
| |
| style = getColumnHeaderStyle(); |
| setStyle(style, HSSFColor.LIGHT_BLUE.index, 12, HSSFColor.BLACK.index, true, |
| CellStyle.ALIGN_CENTER); |
| |
| style = getDateDataStyle(); |
| setStyle(style, HSSFColor.LIGHT_CORNFLOWER_BLUE.index, 12, HSSFColor.BLACK.index, false, |
| CellStyle.ALIGN_RIGHT); |
| |
| style = getDoubleDataStyle(); |
| setStyle(style, HSSFColor.LIGHT_CORNFLOWER_BLUE.index, 12, HSSFColor.BLACK.index, false, |
| CellStyle.ALIGN_RIGHT); |
| setTotalsDoubleStyle(style); |
| |
| style = getIntegerDataStyle(); |
| setStyle(style, HSSFColor.LIGHT_CORNFLOWER_BLUE.index, 12, HSSFColor.BLACK.index, false, |
| CellStyle.ALIGN_RIGHT); |
| setTotalsIntegerStyle(style); |
| |
| // we want the rowHeader style to be like the columnHeader style, just centered differently. |
| final CellStyle newStyle = workbook.createCellStyle(); |
| newStyle.cloneStyleFrom(style); |
| newStyle.setAlignment(CellStyle.ALIGN_LEFT); |
| setRowHeaderStyle(newStyle); |
| } |
| |
| private void setStyle(CellStyle style, short foregroundColor, int fontHeight, short fontColor, |
| boolean isBold, short alignment) { |
| style.setFillForegroundColor(foregroundColor); |
| style.setFillPattern(CellStyle.SOLID_FOREGROUND); |
| Font f = workbook.getFontAt(style.getFontIndex()); |
| f.setFontHeightInPoints((short) fontHeight); |
| f.setFontName(HSSFFont.FONT_ARIAL); |
| f.setColor(fontColor); |
| if(isBold) { |
| f.setBoldweight(Font.BOLDWEIGHT_BOLD); |
| } else { |
| f.setBoldweight(Font.BOLDWEIGHT_NORMAL); |
| } |
| style.setAlignment(alignment); |
| style.setBorderLeft(CellStyle.BORDER_THIN); |
| style.setBorderRight(CellStyle.BORDER_THIN); |
| style.setBorderTop(CellStyle.BORDER_THIN); |
| style.setBorderBottom(CellStyle.BORDER_THIN); |
| style.setLeftBorderColor(HSSFColor.BLACK.index); |
| style.setRightBorderColor(HSSFColor.BLACK.index); |
| style.setTopBorderColor(HSSFColor.BLACK.index); |
| style.setBottomBorderColor(HSSFColor.BLACK.index); |
| } |
| } |