package org.sigmah.server.servlet.exporter.utils;
/*
* #%L
* Sigmah
* %%
* Copyright (C) 2010 - 2016 URD
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFHyperlink;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.hssf.util.HSSFRegionUtil;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
/**
* MS Excel specific common functions
*
* @author sherzod (v1.3)
*/
public class ExcelUtils {
private final HSSFWorkbook wb;
private final CreationHelper createHelper;
private final DataFormat numberFormat;
private final CellStyle borderedBasicStyle;
private final CellStyle borderedDoubleStyle;
private final CellStyle borderedLongStyle;
private final CellStyle borderedDateStyle;
private final CellStyle headerStyle;
private final CellStyle globalExportHeaderStyle;
private final CellStyle topicStyle;
private final CellStyle infoStyle;
private final CellStyle boldInfoStyle;
private final CellStyle linkStyle;
private final CellStyle borderedLinkStyle;
private final CellStyle groupStyle;
private final Map<String, Font> fonts;
public ExcelUtils(final HSSFWorkbook wb) {
this.wb = wb;
createHelper = wb.getCreationHelper();
numberFormat = wb.createDataFormat();
fonts = new HashMap<>();
// ---------------------------------------------------------------------
// Styles
// ---------------------------------------------------------------------
borderedBasicStyle = createBorderedBasicStyle(wb);
borderedDoubleStyle = createBorderedBasicStyle(wb);
borderedDoubleStyle.setDataFormat(numberFormat.getFormat("0.00"));
borderedLongStyle = createBorderedBasicStyle(wb);
borderedLongStyle.setDataFormat(numberFormat.getFormat("#"));
borderedDateStyle = createBorderedBasicStyle(wb);
borderedDateStyle.setDataFormat(createHelper.createDataFormat().getFormat(ExportConstants.DATE_FORMAT_PATTERN));
headerStyle = createHeaderStyle(wb);
globalExportHeaderStyle = createGlobalExportHeaderStyle(wb);
topicStyle = createTopicStyle(wb);
infoStyle = createInfoStyle(wb, false);
boldInfoStyle = createInfoStyle(wb, true);
groupStyle = createGroupStyle(wb);
linkStyle = createLinkStyle(false);
borderedLinkStyle = createLinkStyle(true);
}
public int calculateLineCount(String text, int cellLength) {
if (text == null)
return 1;
int lineCount = text.length() / cellLength;
return ++lineCount;
}
public HSSFCell putBorderedBasicCell(HSSFSheet sheet, int rowIndex, int cellIndex, Object value) {
final HSSFCell cell = sheet.getRow(rowIndex).createCell(cellIndex);
cell.setCellStyle(borderedBasicStyle);
if (value instanceof String) {
cell.setCellValue((String) value);
}
else if (value instanceof Double) {
final double doubleValue = (Double) value;
cell.setCellValue(doubleValue);
cell.setCellStyle(borderedDoubleStyle);
}
else if (value instanceof Long) {
final long longValue = (Long) value;
cell.setCellValue(longValue);
cell.setCellStyle(borderedLongStyle);
}
else if (value instanceof Date) {
cell.setCellValue((Date) value);
cell.setCellStyle(borderedDateStyle);
}
else {
cell.setCellValue("");
}
return cell;
}
public HSSFCell putHeader(HSSFRow row, int cellIndex, String header) {
final HSSFCell cell = row.createCell(cellIndex);
cell.setCellValue(header);
cell.setCellStyle(headerStyle);
return cell;
}
public HSSFCell putGlobalExportHeader(HSSFRow row, int cellIndex, String header) {
final HSSFCell cell = row.createCell(cellIndex);
cell.setCellValue(header);
cell.setCellStyle(globalExportHeaderStyle);
return cell;
}
private CellStyle createGlobalExportHeaderStyle(HSSFWorkbook wb) {
final CellStyle style = createBorderedStyle(wb);
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
final HSSFPalette palette = wb.getCustomPalette();
palette.setColorAtIndex(HSSFColor.GREY_25_PERCENT.index, ExportConstants.GRAY_5_RGB[0], ExportConstants.GRAY_5_RGB[1], ExportConstants.GRAY_5_RGB[2]);
style.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
style.setFillPattern(CellStyle.SOLID_FOREGROUND);
style.setFont(getItalicFont(wb, (short) 10));
style.setWrapText(true);
style.setIndention((short) 1);
return style;
}
public void putMainTitle(final HSSFSheet sheet, int rowIndex, String text, int maxCols) {
final HSSFRow row = sheet.createRow(rowIndex);
row.setHeightInPoints(ExportConstants.HEADER_ROW_HEIGHT);
final HSSFCell cell = row.createCell(1);
cell.setCellValue(text);
cell.setCellStyle(topicStyle);
sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 1, maxCols));
}
public void putInfoRow(final HSSFSheet sheet, int rowIndex, String key, String value, int maxCols) {
int cellIndex = 0;
final HSSFRow row = sheet.createRow(rowIndex);
row.setHeightInPoints(ExportConstants.TITLE_ROW_HEIGHT);
final HSSFCell keyCell = row.createCell(++cellIndex);
keyCell.setCellValue(key);
keyCell.setCellStyle(boldInfoStyle);
final HSSFCell valueCell = row.createCell(++cellIndex);
valueCell.setCellValue(value);
valueCell.setCellStyle(infoStyle);
sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, cellIndex, maxCols));
}
public void putEmptyRow(HSSFSheet sheet, int index, float height) {
sheet.createRow(index).setHeightInPoints(height);
}
private CellStyle createTopicStyle(HSSFWorkbook wb) {
final CellStyle style = wb.createCellStyle();
style.setAlignment(CellStyle.ALIGN_CENTER);
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
style.setFont(getBoldFont(wb, (short) 14));
return style;
}
private CellStyle createHeaderStyle(HSSFWorkbook wb) {
final CellStyle style = createBorderedStyle(wb);
style.setAlignment(CellStyle.ALIGN_CENTER);
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
HSSFPalette palette = wb.getCustomPalette();
palette.setColorAtIndex(HSSFColor.GREY_25_PERCENT.index, ExportConstants.GRAY_10_RGB[0], ExportConstants.GRAY_10_RGB[1], ExportConstants.GRAY_10_RGB[2]);
style.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
style.setFillPattern(CellStyle.SOLID_FOREGROUND);
style.setFont(getBoldFont(wb, (short) 10));
style.setWrapText(true);
return style;
}
public CellStyle getGroupStyle(HSSFWorkbook wb) {
return groupStyle;
}
private CellStyle createGroupStyle(HSSFWorkbook wb) {
final CellStyle style = createBorderedStyle(wb);
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
HSSFPalette palette = wb.getCustomPalette();
palette.setColorAtIndex(HSSFColor.BROWN.index, ExportConstants.LIGHTORANGE_RGB[0], ExportConstants.LIGHTORANGE_RGB[1], ExportConstants.LIGHTORANGE_RGB[2]);
style.setFillForegroundColor(HSSFColor.BROWN.index);
style.setFillPattern(CellStyle.SOLID_FOREGROUND);
style.setFont(getItalicFont(wb, (short) 10));
style.setWrapText(true);
return style;
}
public Font getBoldFont(Workbook wb, short size) {
final String key = "bold" + size;
Font font = fonts.get(key);
if (font == null) {
font = wb.createFont();
font.setFontHeightInPoints(size);
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
fonts.put(key, font);
}
return font;
}
public Font getItalicFont(Workbook wb, short size) {
final String key = "italic" + size;
Font font = fonts.get(key);
if (font == null) {
font = wb.createFont();
font.setFontHeightInPoints(size);
font.setItalic(true);
fonts.put(key, font);
}
return font;
}
private CellStyle createInfoStyle(Workbook wb, boolean bold) {
final Font font = getBoldFont(wb, (short) 11);
if (!bold) {
font.setBoldweight(Font.BOLDWEIGHT_NORMAL);
}
final CellStyle style = wb.createCellStyle();
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
style.setFont(font);
style.setIndention((short) 1);
style.setWrapText(true);
return style;
}
private CellStyle createBorderedBasicStyle(Workbook wb) {
final CellStyle style = createBorderedStyle(wb);
style.setIndention((short) 1);
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
style.setWrapText(true);
style.setAlignment(CellStyle.ALIGN_LEFT);
return style;
}
public void createLinkCell(HSSFCell cell, String value, String target, boolean bordered) {
cell.setCellValue(value);
final HSSFHyperlink link = new HSSFHyperlink(HSSFHyperlink.LINK_DOCUMENT);
link.setAddress("'" + normalizeAsLink(target) + "'!A1");
cell.setHyperlink(link);
if (bordered) {
cell.setCellStyle(borderedLinkStyle);
} else {
cell.setCellStyle(linkStyle);
}
}
private CellStyle createLinkStyle(boolean bordered) {
final Font hlinkFont = wb.createFont();
hlinkFont.setUnderline(Font.U_SINGLE);
hlinkFont.setColor(IndexedColors.BLUE.getIndex());
final CellStyle style;
if (bordered) {
style = createBorderedStyle(wb);
} else {
style = wb.createCellStyle();
}
style.setFont(hlinkFont);
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
style.setIndention((short) 1);
style.setWrapText(true);
return style;
}
/**
* Escape characters which can't be included in a sheet's name.
*
* @param linkName
* Name of a sheet.
* @return The normalized name.
*/
public String normalizeAsLink(String linkName) {
linkName = linkName.replaceAll("('|\\?|\\/|\\[|\\]|\\:)", "_");
linkName = linkName.replace("\\", "_");
linkName = linkName.replace("*", "_");
if (linkName.length() > 25) {
linkName = linkName.substring(0, 25);
}
return linkName;
}
public CellRangeAddress getBorderedRegion(CellRangeAddress region, HSSFSheet sheet, HSSFWorkbook wb) {
final short solid = CellStyle.BORDER_THIN;
HSSFRegionUtil.setBorderBottom(solid, region, sheet, wb);
HSSFRegionUtil.setBorderTop(solid, region, sheet, wb);
HSSFRegionUtil.setBorderLeft(solid, region, sheet, wb);
HSSFRegionUtil.setBorderRight(solid, region, sheet, wb);
HSSFRegionUtil.setBottomBorderColor(IndexedColors.BLACK.getIndex(), region, sheet, wb);
HSSFRegionUtil.setTopBorderColor(IndexedColors.BLACK.getIndex(), region, sheet, wb);
HSSFRegionUtil.setLeftBorderColor(IndexedColors.BLACK.getIndex(), region, sheet, wb);
HSSFRegionUtil.setRightBorderColor(IndexedColors.BLACK.getIndex(), region, sheet, wb);
return region;
}
private CellStyle createBorderedStyle(Workbook wb) {
final CellStyle style = wb.createCellStyle();
style.setBorderRight(CellStyle.BORDER_THIN);
style.setRightBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderBottom(CellStyle.BORDER_THIN);
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderLeft(CellStyle.BORDER_THIN);
style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderTop(CellStyle.BORDER_THIN);
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
return style;
}
}