Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Generating Excel Files with Custom Styles Using EasyExcel

Tech Apr 28 32

Exporting Excel with Custom Cell Styles

When working with EasyExcel, you can apply custom styling to both header and contant cells by implementing a cell style strategy. This approach allows fine-grained control over fonts, colors, aligmnent, and other visual properties.

Service Layer Implementation

@Override
public String generateTemplateFile(HttpServletResponse response) {
    OutputStream outputStream = ExcelHelper.prepareResponseStream(response, "import_template");
    ExcelWriterBuilder writerBuilder = EasyExcel.write(outputStream)
        .registerWriteHandler(new CustomCellStyleHandler())
        .excelType(ExcelTypeEnum.XLSX);
    ExcelWriter excelWriter = writerBuilder.build();

    ExcelHelper.writeToSheet(excelWriter, sampleDataList(), DataDTO.class, 1, "Sample Data");
    ExcelHelper.writeToSheet(excelWriter, descriptionList(), DescriptionDTO.class, 2, "Description");
    
    try {
        ExcelHelper.finalizeExport(outputStream, excelWriter);
    } catch (Exception e) {
        log.error("Export operation failed", e);
    }
    return "Template export finished";
}

Utility Class for Sheet Writing

public static <T> void writeToSheet(ExcelWriter excelWriter, List<T> data, 
                                    Class clazz, Integer sheetNo, String sheetName) {
    ExcelWriterSheetBuilder sheetBuilder = new ExcelWriterSheetBuilder(excelWriter);
    sheetBuilder.sheetNo(sheetNo);
    sheetBuilder.sheetName(sheetName);
    
    WriteSheet writeSheet = new WriteSheet();
    writeSheet.setSheetNo(sheetNo);
    writeSheet.setSheetName(sheetName);
    writeSheet.setClazz(clazz);
    
    excelWriter.write(data, writeSheet);
}

public static void finalizeExport(OutputStream outputStream, ExcelWriter excelWriter) 
    throws IOException {
    outputStream.flush();
    excelWriter.finish();
    outputStream.close();
}

Custom Style Handler Implementation

The custom handler extends AbstractCellStyleStrategy to provide dynamic styling based on cell position and content:

public class CustomCellStyleHandler extends AbstractCellStyleStrategy {

    private WriteCellStyle headerStyle;
    private List<WriteCellStyle> bodyStyleList;
    private CellStyle headerCellStyle;
    private List<CellStyle> bodyCellStyleList;

    public CustomCellStyleHandler(WriteCellStyle headerStyle, 
                                  List<WriteCellStyle> bodyStyleList) {
        this.headerStyle = headerStyle;
        this.bodyStyleList = bodyStyleList;
    }

    public CustomCellStyleHandler(WriteCellStyle headerStyle, WriteCellStyle bodyStyle) {
        this.headerStyle = headerStyle;
        this.bodyStyleList = new ArrayList<>();
        this.bodyStyleList.add(bodyStyle);
    }

    @Override
    protected void initCellStyle(Workbook workbook) {
        if (this.headerStyle != null) {
            this.headerCellStyle = StyleUtils.createHeaderStyle(workbook, this.headerStyle);
        }

        if (this.bodyStyleList != null && !this.bodyStyleList.isEmpty()) {
            this.bodyCellStyleList = new ArrayList<>();
            for (WriteCellStyle cellStyle : this.bodyStyleList) {
                this.bodyCellStyleList.add(StyleUtils.createBodyStyle(workbook, cellStyle));
            }
        }
    }

    @Override
    protected void setHeadCellStyle(Cell cell, Head head, Integer relativeRowIndex) {
        if (this.headerCellStyle != null) {
            cell.setCellStyle(this.headerCellStyle);
        }
    }

    @Override
    protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) {
        if (this.bodyCellStyleList != null && !this.bodyCellStyleList.isEmpty()) {
            Workbook workbook = cell.getSheet().getWorkbook();
            CellStyle style = createDynamicStyle(workbook, cell);
            cell.setCellStyle(style);
        }
    }

    private static CellStyle createDynamicStyle(Workbook workbook, Cell cell) {
        Font font = workbook.createFont();
        font.setFontHeightInPoints((short) 11);
        font.setBold(false);
        font.setItalic(true);
        font.setFontName("Arial");

        CellStyle style = workbook.createCellStyle();
        
        // Apply red color to first data row
        if (cell.getRowIndex() == 1) {
            font.setColor(IndexedColors.RED.getIndex());
        }
        
        style.setFont(font);
        style.setWrapText(true);
        style.setAlignment(HorizontalAlignment.CENTER);
        
        // Special formatting for description rows
        if (cell.getColumnIndex() == 0 && 
            cell.getStringCellValue().contains("Specification")) {
            font.setBold(true);
            style.setAlignment(HorizontalAlignment.LEFT);
        }
        
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        return style;
    }
}

Key Implementation Details

The initCellStyle method converts WriteCellStyle objects to actual CellStyle instances using Apache POI's style utilities. This conversion happens once per workbook for performance optimization.

The setHeadCellStyle and setContentCellStyle methods are called during the write process, allowing for row-specific or cell-specific style decisions based on the relativeRowIndex parameter.

The createDynamicStyle method demonstrates conditional styling logic - applying different formatting based on cell position and content value. This pattern is useful for highlighting specific rows, creating zebra-striping effects, or emphasizing certain data categories.

Related Articles

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

SBUS Signal Analysis and Communication Implementation Using STM32 with Fus Remote Controller

Overview In a recent project, I utilized the SBUS protocol with the Fus remote controller to control a vehicle's basic operations, including movement, lights, and mode switching. This article is aimed...

Comprehensive Guide to Hive SQL Syntax and Operations

This article provides a detailed walkthrough of Hive SQL, categorizing its features and syntax for practical use. Hive SQL is segmented into the following categories: DDL Statements: Operations on...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.