package org.displaytag.export.excel; import org.displaytag.exception.BaseNestableJspTagException; import org.displaytag.exception.SeverityEnum; import org.displaytag.Messages; import org.displaytag.properties.TableProperties; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFDataFormat; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import java.util.Map; import java.util.HashMap; /** * Convenience methods for the excel export. Contains code extracted from several existing classes. * @author andy * Date: Nov 13, 2010 * Time: 10:16:33 AM */ public class ExcelUtils { public final static String EXCEL_SHEET_NAME = "export.excel.sheetname"; //$NON-NLS-1$ public final static String EXCEL_FORMAT_INTEGER = "export.excel.format.integer"; //$NON-NLS-1$ public final static String EXCEL_FORMAT_DATE = "export.excel.format.date"; //$NON-NLS-1$ public final static String EXCEL_FORMAT_NUMBER = "export.excel.format.number"; //$NON-NLS-1$ public final static String EXCEL_WRAPAT = "export.excel.wraptextlength"; //$NON-NLS-1$ /* * Available already configured cell styles, as HSSF JavaDoc claims there are limits to cell styles. */ private Map<String, HSSFCellStyle> cellStyles = new HashMap<String, HSSFCellStyle>(); /** * Max line length for wrapping. */ private int wrapAt; // public static final Integer /** * Style constant for looking up cell styles. */ public static final String STYLE_INTEGER = "integer"; /** * Style constant for looking up cell styles. */ public static final String STYLE_NUMBER = "number"; /** * Style constant for looking up cell styles. */ public static final String STYLE_DATE = "date"; /** * Style constant for looking up cell styles. */ public static final String STYLE_STRING = "string"; /** * Style constant for looking up cell styles. */ public static final String STYLE_LONGSTRING = "longstring"; /** * Style constant for looking up cell styles. */ public static final String STYLE_PCT = "pct"; /** * Workbook */ private HSSFWorkbook wb; public ExcelUtils(HSSFWorkbook book) { wb = book; } public HSSFWorkbook getWb() { return wb; } public void setWb(HSSFWorkbook wb) { this.wb = wb; } /** * We cache the styles; they are expensive to construct. * @param properties props for this run */ public void initCellStyles(TableProperties properties) { // Integer HSSFCellStyle style = getNewCellStyle(); style.setAlignment(HSSFCellStyle.ALIGN_RIGHT); style.setDataFormat(HSSFDataFormat.getBuiltinFormat( properties.getProperty(ExcelUtils.EXCEL_FORMAT_INTEGER) )); cellStyles.put(STYLE_INTEGER, style); // NUMBER style = getNewCellStyle(); style.setAlignment(HSSFCellStyle.ALIGN_RIGHT); style.setDataFormat(HSSFDataFormat.getBuiltinFormat(properties.getProperty(ExcelUtils.EXCEL_FORMAT_NUMBER))); cellStyles.put(STYLE_NUMBER, style); // style = HSSFDataFormat.getBuiltinFormat("0.00%"); // Date style = getNewCellStyle(); style.setAlignment(HSSFCellStyle.ALIGN_RIGHT); style.setDataFormat(HSSFDataFormat.getBuiltinFormat(properties.getProperty(ExcelUtils.EXCEL_FORMAT_DATE))); style.setAlignment(HSSFCellStyle.ALIGN_RIGHT); cellStyles.put(STYLE_DATE, style); // Long text style = getNewCellStyle(); // http://jakarta.apache.org/poi/hssf/quick-guide.html#NewLinesInCells style.setWrapText(true); cellStyles.put(STYLE_LONGSTRING, style); // Regular text cellStyles.put(STYLE_STRING, getNewCellStyle()); wrapAt = Integer.valueOf(properties.getProperty(ExcelUtils.EXCEL_WRAPAT)); } /** * You can add styles too, but they won't be picked up unless you do so in a subclass. * @param key * @param st */ public void addCellStyle(String key, HSSFCellStyle st) { cellStyles.put(key,st); } public HSSFCellStyle getNewCellStyle() { return getWb() == null ? null : getWb().createCellStyle(); } public HSSFCellStyle getStyle(String clz) { return cellStyles.get(clz); } public enum CellFormatTypes { INTEGER, NUMBER, DATE } /** * Wraps IText-generated exceptions. * @author Fabrizio Giustina * @version $Revision: 1163 $ ($Author: rapruitt $) */ static class ExcelGenerationException extends BaseNestableJspTagException { /** * D1597A17A6. */ private static final long serialVersionUID = 899149338534L; /** * Instantiate a new PdfGenerationException with a fixed message and the given cause. * @param cause Previous exception */ public ExcelGenerationException(Throwable cause) { super(ExcelHssfView.class, Messages.getString("ExcelView.errorexporting"), cause); //$NON-NLS-1$ } /** * @see org.displaytag.exception.BaseNestableJspTagException#getSeverity() */ public SeverityEnum getSeverity() { return SeverityEnum.ERROR; } } /** * Set the cell to wrap if the text is this long. * @return the max length for not wrapping */ public int getWrapAtLength() { return wrapAt; } // patch from Karsten Voges /** * Escape certain values that are not permitted in excel cells. * @param rawValue the object value * @return the escaped value */ public static String escapeColumnValue(Object rawValue) { if (rawValue == null) { return null; } // str = Patterns.replaceAll(str, "(\\r\\n|\\r|\\n|\\n\\r)\\s*", ""); String returnString = ObjectUtils.toString(rawValue); // escape the String to get the tabs, returns, newline explicit as \t \r \n returnString = StringEscapeUtils.escapeJava(StringUtils.trimToEmpty(returnString)); // remove tabs, insert four whitespaces instead returnString = StringUtils.replace(StringUtils.trim(returnString), "\\t", " "); // remove the return, only newline valid in excel returnString = StringUtils.replace(StringUtils.trim(returnString), "\\r", " "); // unescape so that \n gets back to newline returnString = StringEscapeUtils.unescapeJava(returnString); return returnString; } }