easyexcel 自定义列的导出

公司最近有个需求 就是将day这一列 变为excel表格表头,然后列显示薪水。
在这里插入图片描述
然后再到网上找教程最终终于找到相关的大神写的博客,具体网址忘记了。抱歉。现在写下具体教程。

  1. ExcelHead 代码
import lombok.Data;

/**
 * @author hunterhou
 * @date 2023/2/28 10:14
 */
@Data
public class ExcelHead<T> {

    //内容里的字段名称
    private String fieldName;
    //显示值,一般为中文的
    private String title;
    private T nullValue; //如果为null情况下要显示的值

    public ExcelHead(String fieldName, String title) {
        this.fieldName = fieldName;
        this.title = title;
    }

    public ExcelHead(String fieldName, String title, T nullValue) {
        this.fieldName = fieldName;
        this.title = title;
        this.nullValue = nullValue;
    }
}

ExcelUtils

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.google.common.collect.Lists;
import com.ltu.util.easyexcel.HorizontalCellStyleStrategy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author hunterhou
 * @date 2023/2/28 9:18
 */
public class ExcelUtils<T> {

//    public static void main(String[] args) {
//        String filePath = "d:\\temp\\a.xlsx";
        List<ExcelHead> headList = new ArrayList();
        headList.add(new ExcelHead<String>("23-05-05", "23-05-05",""));
        headList.add(new ExcelHead<String>("23-05-06", "23-05-06", ""));


        List<Map<String, Object>> dataList = new ArrayList();
        Map<String, Object> one = new HashMap();
        one.put("23-05-05", "285.65");
        one.put("23-05-06", "257.36");
        dataList.add(one);

        Map<String, Object> two = new HashMap();
        two.put("23-05-05", "283.65");
        two.put("23-05-06", "25712.36");
        dataList.add(two);

//        Map<String, Object> there = new HashMap();
//        there.put("name", "不知道年龄");
//        there.put("age", null);
//        dataList.add(there);
        ExcelUtils.write(filePath, headList, dataList);
//
//
//        List<ExcelHead> headList2 = new ArrayList();
//        headList2.add(new ExcelHead<String>("dept", "部门", ""));
//        headList2.add(new ExcelHead<String>("code", "工号", ""));
//        headList2.add(new ExcelHead<String>("name", "姓名", ""));
//        headList2.add(new ExcelHead<String>("23-05-05", "23-05-05",""));
//        headList2.add(new ExcelHead<String>("23-05-06", "23-05-06", ""));
//        headList2.add(new ExcelHead<String>("23-05-07", "23-05-07", ""));
//
//        List<Map<String, Object>> dataList2 = new ArrayList();
//        Map<String, Object> one2 = new HashMap();
//        one2.put("code", "A001");
//        one2.put("23-05-05", "285.65");
//        one2.put("23-05-06", "257.36");
//        one2.put("23-05-07", "25734.36");
//        dataList2.add(one2);
//
//        Map<String, Object> two2 = new HashMap();
//        two2.put("code", "A002");
//        two2.put("23-05-05", "283.65");
//        two2.put("23-05-06", "25712.36");
//        two2.put("23-05-07", "25712e2.36");
//        dataList2.add(two2);
//
//        ExcelUtils.write(filePath, headList2, dataList2);
//
//    }

    /**
     * 写excel
     *
     * @param filePath 保存的路径名
     * @param headList
     * @param dataList
     */
    public static void write(String filePath, List<ExcelHead> headList, List<Map<String, Object>> dataList) {
        ExcelWriterBuilder writerBuilder = EasyExcel.write();
        writerBuilder.file(filePath);
        writerBuilder.excelType(ExcelTypeEnum.XLSX);
        writerBuilder.autoCloseStream(true);

        writerBuilder.head(convertHead(headList)).sheet("sheet1")
                .doWrite(convertData(headList, dataList));
    }

    /**
     * 写excel
     *
     * @param filePath 保存的路径名
     * @param headList 表头
     * @param dataList 数据源
     * @param sheetName  sheet名称
     */
    public static void write(String filePath, List<ExcelHead> headList, List<Map<String, Object>> dataList,String sheetName) {
        ExcelWriterBuilder writerBuilder = EasyExcel.write();
        writerBuilder.file(filePath);
        writerBuilder.excelType(ExcelTypeEnum.XLSX);
        writerBuilder.autoCloseStream(true);

        writerBuilder.head(convertHead(headList)).sheet(sheetName)
                .doWrite(convertData(headList, dataList));
    }


    /**
     * 写excel
     *
     * @param filePath 保存的路径名
     * @param headList 表头
     * @param dataList 数据源
     * @param sheetName  sheet名称
     * @param horizontalCellStyleStrategy  单元格样式设置
     */
    public static void write(String filePath, List<ExcelHead> headList, List<Map<String, Object>> dataList, String sheetName, HorizontalCellStyleStrategy horizontalCellStyleStrategy) {
        ExcelWriterBuilder writerBuilder = EasyExcel.write();
        writerBuilder.file(filePath);
        writerBuilder.excelType(ExcelTypeEnum.XLSX);
        writerBuilder.autoCloseStream(true);

        writerBuilder.head(convertHead(headList))
                .sheet(sheetName)
                // 设置单元格样式
                .registerWriteHandler(horizontalCellStyleStrategy)
                .doWrite(convertData(headList, dataList));
    }


    /**
     * 会先删除excel所有sheet,再写入
     */
    public static <T> void writeSheet(String filePath, String sheetName, Class<T> c, List<T> list) {
        EasyExcel.write(filePath, c).sheet(sheetName).doWrite(list);
    }

    public static <T> List<T> read(String fileName, String sheetName, Class c) {

        List<T> list = new ArrayList();
        EasyExcel.read(fileName, c, new ReadListener<T>() {
            @Override
            public void invoke(T o, AnalysisContext analysisContext) {
                list.add(o);
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {

            }
        }).sheet(sheetName).doRead();
        return list;
    }


    private static List<List<String>> convertHead(List<ExcelHead> headList) {
        List<List<String>> list = new ArrayList<>();
        for (ExcelHead head : headList) {
            list.add(Lists.newArrayList(head.getTitle()));
        }
        //沒有搞清楚head的参数为List<List<String>>,用List<String>就OK了
        return list;
    }

    /**
     * @param headList
     * @param dataList key为head里的fieldName
     * @return
     */
    private static List<List<Object>> convertData(List<ExcelHead> headList, List<Map<String, Object>> dataList) {
        List<List<Object>> result = new ArrayList();
        //对dataList转为easyExcel的数据格式
        for (Map<String, Object> data : dataList) {
            List<Object> row = new ArrayList();
            for (ExcelHead h : headList) {
                Object o = data.get(h.getFieldName());
                //需要对null的处理,比如age的null,要转为对应设置的值
                row.add(handler(o, h.getNullValue()));
            }
            result.add(row);
        }
        return result;
    }

    /**
     * null值处理
     *
     * @param o
     * @param nullValue
     * @return
     */
    private static Object handler(Object o, Object nullValue) {
        return o != null ? o : nullValue;
    }
}

设置单元格样式

import java.util.List;

import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;

import com.alibaba.excel.write.style.AbstractCellStyleStrategy;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;


@Getter
@Setter
@EqualsAndHashCode
public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy {

    private WriteCellStyle headWriteCellStyle;
    private List<WriteCellStyle> contentWriteCellStyleList;

    public HorizontalCellStyleStrategy() {
    }

    public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle,
                                       List<WriteCellStyle> contentWriteCellStyleList) {
        this.headWriteCellStyle = headWriteCellStyle;
        this.contentWriteCellStyleList = contentWriteCellStyleList;
    }

    public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle, WriteCellStyle contentWriteCellStyle) {
        this.headWriteCellStyle = headWriteCellStyle;
        if (contentWriteCellStyle != null) {
            this.contentWriteCellStyleList = ListUtils.newArrayList(contentWriteCellStyle);
        }
    }

    @Override
    protected void setHeadCellStyle(CellWriteHandlerContext context) {
        if (stopProcessing(context) || headWriteCellStyle == null) {
            return;
        }
        WriteCellData<?> cellData = context.getFirstCellData();
        WriteCellStyle.merge(headWriteCellStyle, cellData.getOrCreateStyle());
    }

    @Override
    protected void setContentCellStyle(CellWriteHandlerContext context) {
        if (stopProcessing(context) || CollectionUtils.isEmpty(contentWriteCellStyleList)) {
            return;
        }
        WriteCellData<?> cellData = context.getFirstCellData();
        if (context.getRelativeRowIndex() == null || context.getRelativeRowIndex() <= 0) {
            WriteCellStyle.merge(contentWriteCellStyleList.get(0), cellData.getOrCreateStyle());
        } else {
            WriteCellStyle.merge(
                    contentWriteCellStyleList.get(context.getRelativeRowIndex() % contentWriteCellStyleList.size()),
                    cellData.getOrCreateStyle());
        }
    }

    protected boolean stopProcessing(CellWriteHandlerContext context) {
        return context.getFirstCellData() == null;
    }

}

import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import org.apache.poi.ss.usermodel.*;

public class StyleUtils {

    /**
     * 标题样式
     * @return
     */
    public static WriteCellStyle getHeadStyle(){
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景颜色
//        headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE1.getIndex());
//        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

        // 字体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontName("宋体");//设置字体名字
        headWriteFont.setFontHeightInPoints((short)14);//设置字体大小
        headWriteFont.setBold(true);//字体加粗
        headWriteCellStyle.setWriteFont(headWriteFont); //在样式用应用设置的字体;

        // 样式
        headWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
        headWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
        headWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //设置左边框;
        headWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
        headWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
        headWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
        headWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
        headWriteCellStyle.setTopBorderColor((short) 0); //设置顶边框颜色;

        headWriteCellStyle.setWrapped(true);  //设置自动换行;

        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);//设置水平对齐的样式为居中对齐;
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);  //设置垂直对齐的样式为居中对齐;
        headWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适

        return headWriteCellStyle;
    }


    /**
     * 内容样式
     * @return
     */
    public static WriteCellStyle getContentStyle(){
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();

        // 背景绿色
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
//        contentWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
//        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

        // 设置字体
        WriteFont contentWriteFont = new WriteFont();
        contentWriteFont.setFontHeightInPoints((short) 12);//设置字体大小
        contentWriteFont.setFontName("宋体"); //设置字体名字
        contentWriteCellStyle.setWriteFont(contentWriteFont);//在样式用应用设置的字体;

        //设置样式;
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
        contentWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //设置左边框;
        contentWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
        contentWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
        contentWriteCellStyle.setTopBorderColor((short) 0); ///设置顶边框颜色;

        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 水平居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
        contentWriteCellStyle.setWrapped(true); //设置自动换行;

//        contentWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适

        return contentWriteCellStyle;
    }
}

使用案例

public CodeDataResp exportWorkFeeByDate(UserWorkProcedureEntity req, HttpServletResponse response){
        String   sheetName ="人员工资明细表";
        String startTime = null;
        String endTime = null;

        String now = DateUtil.now();
        String threeDaysAgoStart = DateUtil.format(DateUtil.offsetDay(DateUtil.beginOfDay(new Date()), -3), "yyyy-MM-dd HH:mm:ss");
        // 默认查3天内的
        // 设置开始时间为 3天前的 开始
        startTime = StringUtils.isNotBlank(req.getStartTime())?req.getStartTime():threeDaysAgoStart;
        // 结束时间为 now
        endTime = StringUtils.isNotBlank(req.getEndTime())?req.getEndTime():now;
        QueryWrapper<UserWorkProcedureEntity> wrapper2 = new QueryWrapper<UserWorkProcedureEntity>();
        wrapper2.lambda().ge(UserWorkProcedureEntity :: getCreateTime, startTime);
        // 结束时间为 now
        wrapper2.lambda().le(UserWorkProcedureEntity :: getCreateTime, endTime);
        // 姓名过滤
        if (StringUtils.isNotBlank(req.getKeyWords())){
            wrapper2.lambda().like(UserWorkProcedureEntity :: getUserName,req.getKeyWords());
        }
        // 工号过滤
        if (StringUtils.isNotBlank(req.getKeyWords2())){
            wrapper2.lambda().eq(UserWorkProcedureEntity :: getUserCode,req.getKeyWords2());
        }

        List<SalaryByDateVO> data = userWorkProcedureMapper.exportWorkFeeByDate(wrapper2);

        if(CollectionUtils.isEmpty(data))
            return  CodeDataResp.valueOfFailed("无记录");

        String fileName = DatePattern.PURE_DATETIME_FORMAT.format(new Date())+sheetName+".xlsx";
        String folderStr="export-excel";
        String userDir = System.getProperties().getProperty("user.dir").concat(File.separator).concat("static");
        String uploadPath = userDir.concat(File.separator).concat(folderStr);
        String filePath = uploadPath.concat(File.separator).concat(fileName);
        String  returnPath=folderStr.concat("/").concat(fileName);

        // 定义表头和数据格式
        List<ExcelHead> headList = new ArrayList();
        headList.add(new ExcelHead<String>("dept", "部门", ""));
        headList.add(new ExcelHead<String>("code", "工号", ""));
        headList.add(new ExcelHead<String>("name", "姓名", ""));
        // 设置日期
        Set<Date> set = new TreeSet<>();
        data.forEach(i->{
            set.add(i.getDay());
        });
        set.forEach(i->{
            String date = DateUtil.format(i, "yyyy-MM-dd");
            headList.add(new ExcelHead(date, date+"工资", 0));
        });
        // 定位 列   日期作为主键
        Map<String,List<Map<String,String>>> map = new HashMap<>();
        Map<String,String> deptMap = new HashMap<>();
        Map<String,String> nameMap = new HashMap<>();
        // 定位 行   某个部门的某个人 工号
        data.forEach(i->{
            // 时间格式化
            String date= DateUtil.format(i.getDay(), "yyyy-MM-dd");
            String key = i.getUserCode();
            if (!deptMap.containsKey(key)){
                deptMap.put(key,i.getGroupName());
            }
            if (!nameMap.containsKey(key)){
                nameMap.put(key,i.getUserName());
            }
            Map<String,String> oneMap = new HashMap<>();
            // 保留两位小数
            oneMap.put(date,String.format("%.2f", (double) i.getTotalSalary() / 100));
            if (map.containsKey(key)){
                map.get(key).add(oneMap);
            }else {
                //
                List<Map<String,String>> salaryList = new ArrayList<>();
                salaryList.add(oneMap);
                map.put(key,salaryList);
            }
        });
        List<Map<String, Object>> dataList = new ArrayList();
        List<Map<String, Object>> finalDataList = dataList;
        map.forEach((k, v)->{
            Map<String, Object> one = new HashMap();
            one.put("code",k);
            one.put("name",nameMap.get(k));
            one.put("dept",deptMap.get(k));
            // 把值设置进去
            v.forEach(one::putAll);
            finalDataList.add(one);
        });
        // List 根据 部门 姓名 排序
        dataList = dataList.stream()
                .sorted(Comparator.comparing(m -> {
                    String dept = (String) m.get("dept");
                    String name = (String) m.get("name");
                    return dept == null ? "" : dept + "-" + (name == null ? "" : name);
                }))
                .collect(Collectors.toList());
        // 设置单元格样式
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(StyleUtils.getHeadStyle(), StyleUtils.getContentStyle());
        ExcelUtils.write(filePath, headList, dataList,fileName,horizontalCellStyleStrategy);
        return  CodeDataResp.valueOfSuccess(returnPath);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值