Pregunta

My system produces lots of different Excel reports using Apache POI from Java.

A lot of these reports share the same styles.

I have created a CellStyle library for use by all of the reports. I wondered if there was a neater way.

import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Workbook;

public class CellStyles {
    CellStyle headingCellStyle = null;
    Workbook wb;

    public CellStyles(Workbook wb) {
        this.wb = wb;
    }

    public CellStyle getHeadingCellStyle() {
        if (headingCellStyle == null) {
            headingCellStyle = wb.createCellStyle();
            headingCellStyle.setFillForegroundColor(HSSFColor.YELLOW.index);
            headingCellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        }
        return headingCellStyle;
    }

}

and then calling it

Workbook wb = new XSSFWorkbook(inputStream); // XSSF for .xlsm
CellStyles cs = new CellStyles(wb);


CellUtil.getCell(myRow, 2).setCellStyle(cs.getHeadingCellStyle());
¿Fue útil?

Solución

I think that given its simplicity this solution it is good.

Unfortunately in POI CellStyle needs to be created from Workbook so you can't really avoid passing wb as a parameter in some way.

In addition to your implementation you might try to expose in CellStyles a bunch of static methods taking wb as a parameter and returning the style, so that you don't need to pass cs object around in your code. Though I wouldn't say it's worth it as to do it properly you'd need to maintain the static cache of Map[Workbook, CellStyles] mappings, which would use for returning the style.

Lazy initialization of styles works well too and allows you to avoid creating duplicate styles, though it would be better to keep styles private i.e. private CellStyle headingCellStyle = null; to ensure nothing can change the style assignment outside the class and null-valued headerCellStyle won't be used by accident.

Otros consejos

I have a project which converts HTML/CSS to various formats including Excel and ODF. If it's of any use, I do the following where Style is a class holding the various properties extracted from the CSS.

public class ExcelStyleGenerator {
    private Map<Style, XSSFCellStyle> styles;

    public ExcelStyleGenerator() {
        styles = new HashMap<Style, XSSFCellStyle>();
    }

    public CellStyle getStyle(Cell cell, Style style) {
        XSSFCellStyle cellStyle;

        if (styles.containsKey(style)) {
            cellStyle = styles.get(style);
        } else {
            cellStyle = (XSSFCellStyle) cell.getSheet().getWorkbook().createCellStyle();

            applyBackground(style, cellStyle);
            applyBorders(style, cellStyle);
            applyFont(cell, style, cellStyle);
            applyHorizontalAlignment(style, cellStyle);
            applyverticalAlignment(style, cellStyle);
            applyWidth(cell, style);

            styles.put(style, cellStyle);
        }

        return cellStyle;
    }

    protected void applyBackground(Style style, XSSFCellStyle cellStyle) {
        if (style.isBackgroundSet()) {
            cellStyle.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
            cellStyle.setFillForegroundColor(new XSSFColor(style.getProperty(CssColorProperty.BACKGROUND)));
        }
    }

    protected void applyBorders(Style style, XSSFCellStyle cellStyle) {
        if (style.isBorderWidthSet()) {
            short width = (short) style.getProperty(CssIntegerProperty.BORDER_WIDTH);

            Color color = style.getProperty(CssColorProperty.BORDER_COLOR) != null ? style
                    .getProperty(CssColorProperty.BORDER_COLOR) : Color.BLACK;

            cellStyle.setBorderBottom(BorderStyle.THIN);
            cellStyle.setBorderBottom(width);
            cellStyle.setBottomBorderColor(new XSSFColor(color));

            cellStyle.setBorderTop(BorderStyle.THIN);
            cellStyle.setBorderTop(width);
            cellStyle.setTopBorderColor(new XSSFColor(color));

            cellStyle.setBorderLeft(BorderStyle.THIN);
            cellStyle.setBorderLeft(width);
            cellStyle.setLeftBorderColor(new XSSFColor(color));

            cellStyle.setBorderRight(BorderStyle.THIN);
            cellStyle.setBorderRight(width);
            cellStyle.setRightBorderColor(new XSSFColor(color));
        }
    }

    protected void applyFont(Cell cell, Style style, XSSFCellStyle cellStyle) {
        Font font = createFont(cell.getSheet().getWorkbook(), style);
        cellStyle.setFont(font);
    }

    protected void applyHorizontalAlignment(Style style, XSSFCellStyle cellStyle) {
        if (style.isHorizontallyAlignedLeft()) {
            cellStyle.setAlignment(HorizontalAlignment.LEFT);
        } else if (style.isHorizontallyAlignedRight()) {
            cellStyle.setAlignment(HorizontalAlignment.RIGHT);
        } else if (style.isHorizontallyAlignedCenter()) {
            cellStyle.setAlignment(HorizontalAlignment.CENTER);
        }
    }

    protected void applyverticalAlignment(Style style, XSSFCellStyle cellStyle) {
        if (style.isVerticallyAlignedTop()) {
            cellStyle.setVerticalAlignment(VerticalAlignment.TOP);
        } else if (style.isVerticallyAlignedBottom()) {
            cellStyle.setVerticalAlignment(VerticalAlignment.BOTTOM);
        } else if (style.isVerticallyAlignedMiddle()) {
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        }
    }

    protected void applyWidth(Cell cell, Style style) {
        if (style.getProperty(CssIntegerProperty.WIDTH) > 0) {
            cell.getSheet().setColumnWidth(cell.getColumnIndex(), style.getProperty(CssIntegerProperty.WIDTH) * 50);
        }
    }

    public Font createFont(Workbook workbook, Style style) {
        Font font = workbook.createFont();

        if (style.isFontNameSet()) {
            font.setFontName(style.getProperty(CssStringProperty.FONT_FAMILY));
        }

        if (style.isFontSizeSet()) {
            font.setFontHeightInPoints((short) style.getProperty(CssIntegerProperty.FONT_SIZE));
        }

        if (style.isColorSet()) {
            Color color = style.getProperty(CssColorProperty.COLOR);

            // if(! color.equals(Color.WHITE)) // POI Bug
            // {
            ((XSSFFont) font).setColor(new XSSFColor(color));
            // }
        }

        if (style.isFontBold()) {
            font.setBoldweight(Font.BOLDWEIGHT_BOLD);
        }

        font.setItalic(style.isFontItalic());

        if (style.isTextUnderlined()) {
            font.setUnderline(Font.U_SINGLE);
        }

        return font;
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top