EasyExcel设置行中单个单元格的样式

1. 前言

在近期的工作中遇到一个导出Excel的需求:
用户通过Excel导入信息,校验用户导入的信息是否合法;如果导入的信息不合法,则保存失败;并且需要精确到行的字段设置标识,然后再将用户导入的信息以文件的方式返回给用户。如果导入的信息合法则保存成功内容存储到库中。
其实并不难看出来,如果导入的数据有误,那么就转换成有样式导出了。
导出Excel文件的技术使用的是阿里巴巴提供的一个EasyExcel工具,有关easyExcel相关的单个单元格样式设置的资料比较少,自己也是查阅了大量的资料,最后也是在尝试的过程中实现了功能,借此记录一下。

2.最终的效果图

在这里插入图片描述

3.实现

EasyExcel在写出文件的时候是以行为单位对外写出的(详细来说先是第i行,然后是这行中的第i个单元格依次写出),EasyExcel在写出的时候提供了一个写出时的拦截器CellWriteHandler接口,拦截处理单元格创建,我们可以在这个拦截器中对行中的每个或者单个指定的单元格设置样式。

第一步:我们需要写一个类来实现CellWriteHandler接口

CellColorSheetWriteHandler.java

package com.scholartang.util.excel;

import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.util.StyleUtil;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import org.apache.poi.ss.usermodel.*;
import java.util.HashMap;
import java.util.List;

/**
 * @Author ScholarTang
 * @Date 2020/8/14 5:10 下午
 * @Desc 拦截处理单元格创建
 */
public class CellColorSheetWriteHandler implements CellWriteHandler {
    
    
    /**
     * map
     * key:第i行
     * value:第i行中单元格索引集合
     */
    private HashMap<Integer,List<Integer>> map;
    
    /**
     * 颜色
     */
    private Short colorIndex;

    /**
     * 有参构造
     */
    public CellColorSheetWriteHandler(HashMap<Integer, List<Integer>> map, Short colorIndex) {
    
    
        this.map = map;
        this.colorIndex = colorIndex;
    }

    /**
     * 无参构造
     */
    public CellColorSheetWriteHandler() {
    
    

    }

    /**
     * 在创建单元格之前调用
     */
    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
    
    
    }

    /**
     * 在单元格创建后调用
     */
    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
    
    
    }

    /**
     * 在单元上的所有操作完成后调用
     */
    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
    
    

        /**
         * 考虑到导出数据量过大的情况,不对每一行的每一个单元格进行样式设置,只设置必要行中的某个单元格的样式
         */
        //当前行的第i列
        int i = cell.getColumnIndex();
        //不处理第一行
        if (0 != cell.getRowIndex()) {
    
    
            List<Integer> integers = map.get(cell.getRowIndex());
            if (integers != null && integers.size() > 0) {
    
    
                if (integers.contains(i)) {
    
    
                    // 根据单元格获取workbook
                    Workbook workbook = cell.getSheet().getWorkbook();
                    //设置行高
                    writeSheetHolder.getSheet().getRow(cell.getRowIndex()).setHeight((short) (1.4 * 256));
                    // 单元格策略
                    WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
                    // 设置背景颜色白色
                    contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
                    // 设置垂直居中为居中对齐
                    contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
                    // 设置左右对齐为靠左对齐
                    contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
                    // 设置单元格上下左右边框为细边框
                    contentWriteCellStyle.setBorderBottom(BorderStyle.MEDIUM);
                    contentWriteCellStyle.setBorderLeft(BorderStyle.MEDIUM);
                    contentWriteCellStyle.setBorderRight(BorderStyle.MEDIUM);
                    contentWriteCellStyle.setBorderTop(BorderStyle.MEDIUM);
                    // 创建字体实例
                    WriteFont cellWriteFont = new WriteFont();
                    // 设置字体大小
                    cellWriteFont.setFontName("宋体");
                    cellWriteFont.setFontHeightInPoints((short) 14);
                    //设置字体颜色
                    cellWriteFont.setColor(colorIndex);
                    //单元格颜色
                    contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
                    contentWriteCellStyle.setWriteFont(cellWriteFont);
                    CellStyle cellStyle = StyleUtil.buildHeadCellStyle(workbook, contentWriteCellStyle);
                    //设置当前行第i列的样式
                    cell.getRow().getCell(i).setCellStyle(cellStyle);
                }
            }
        }
    }
}






说明:
CellColorSheetWriteHandler类是我自定义的类,用来实现CellWriteHandler接口,需要重写接口中的三个抽象方法。除此之外我还在类中定义了两个成员变量: mapcolorIndex
map:用来记录需要为第key行中的第value.get(i)列设置样式
colorIndex:表示单元格需要设置的颜色

第二步:准备一些数据,写一个测试类来测试导出

package com.scholartang.util;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.scholartang.model.po.Products;
import com.scholartang.util.excel.CellColorSheetWriteHandler;

import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;

import java.util.*;

/**
 * @Author ScholarTang
 * @Date 2020/8/15 5:31 下午
 * @Desc 测试类
 */

public class Test {
    
    
    /**
     * 导出的数据集合
     */
    public static List<Products> productsList;
    static {
    
    
        productsList = new ArrayList<>();
        Collections.addAll(productsList,
                new Products(null, "华为P20", 4999.0, "上架", null, 10000, "华为"),
                new Products(null, "华为P30", 5999.0, "上架", null, 10000, "华为"),
                new Products(null, "华为P40", 6999.0, "上架", null, 10000, "华为"),
                new Products(null, "华为P50", 7999.0, "上架", null, 10000, "华为"),
                new Products(null, "华为P60", 8999.0, "上架", null, 10000, "华为"),
                new Products(null, "华为P70", 9999.0, "上架", null, 10000, "华为")
        );
    }

    public static void main(String[] args) {
    
    
        String fileName = ("/Users/jiangnan/Desktop/商品信息.xlsx");
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = defaultStyles();
        //设置默认样式
        ExcelWriterSheetBuilder writerSheetBuilder = EasyExcel.write(fileName, Products.class).sheet("data").registerWriteHandler(horizontalCellStyleStrategy);
        //用来记录需要为第`key`行中的第`value.get(i)`列设置样式
        HashMap<Integer, List<Integer>> map = new HashMap<>();
        map.put(1, Arrays.asList(2, 5));
        map.put(2, Arrays.asList(1, 2, 4));
        map.put(4, Arrays.asList(1, 2, 4));
        //指定单元格样式
        CellColorSheetWriteHandler writeHandler = new CellColorSheetWriteHandler(map, IndexedColors.RED.getIndex());
        //添加样式
        writerSheetBuilder.registerWriteHandler(writeHandler);
        //导出
        writerSheetBuilder.doWrite(productsList);
    }

    /**
     * 默认样式
     * @return
     */
    public static HorizontalCellStyleStrategy defaultStyles(){
    
    
        //TODO 默认样式
        //表头样式策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //设置表头居中对齐
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //表头前景设置淡蓝色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setBold(true);
        headWriteFont.setFontName("宋体");
        headWriteFont.setFontHeightInPoints((short) 12);
        headWriteCellStyle.setWriteFont(headWriteFont);

        //内容样式策略策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 设置背景颜色白色
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        // 设置垂直居中为居中对齐
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        // 设置左右对齐为靠左对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        // 设置单元格上下左右边框为细边框
        contentWriteCellStyle.setBorderBottom(BorderStyle.MEDIUM);
        contentWriteCellStyle.setBorderLeft(BorderStyle.MEDIUM);
        contentWriteCellStyle.setBorderRight(BorderStyle.MEDIUM);
        contentWriteCellStyle.setBorderTop(BorderStyle.MEDIUM);
        //创建字体对象
        WriteFont contentWriteFont = new WriteFont();
        //内容字体大小
        contentWriteFont.setFontName("宋体");
        contentWriteFont.setFontHeightInPoints((short) 14);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 初始化表格样式
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        return horizontalCellStyleStrategy;
    }
}








猜你喜欢

转载自blog.csdn.net/ScholarTang/article/details/108024953
今日推荐