easyExcel使用模版填充excel,合并单元格

一、最终效果

二、制作模版

1、制作填充模版

模版在代码中保存的位置

2、Controller

bash 复制代码
/**
 * 下载模板
 */
@RequestMapping(value = "exportData")
public void exportData(KqKqb kqKqb,HttpServletResponse response, HttpServletRequest request) throws IOException {
	kqKqbService.exportData(kqKqb,response,request);
}

3、Service(获取数据的逻辑不重要,重点单元格合并)

bash 复制代码
public void exportData(KqKqb kqKqb,HttpServletResponse response, HttpServletRequest request) throws IOException {
        //获取填充数据
        KqKqb entity = dao.get(kqKqb);
        Integer ycqts = entity.getYcqts();//本月应出勤天数
        String officeName = entity.getOfficeName();//单位名称
        List<Map<String, Object>> mapLit = ListUtils.newArrayList();
        KqKqbZb zbSql = new KqKqbZb();
        zbSql.setMonth(entity.getMonth());
        zbSql.setOfficeCode(entity.getOfficeCode());
        List<KqKqbZb> zbList = zbDao.findList(zbSql);
        String year =  kqKqb.getMonth().split("-")[0];
        String month =  kqKqb.getMonth().split("-")[1];

        //list填充数据封装
        String empCode = "";
        Integer xh = 0;
        for (KqKqbZb kqKqbZb : zbList) {
            //工号不重复序列加号加自增1
            if(!empCode.equals(kqKqbZb.getEmpCode())){
                empCode = kqKqbZb.getEmpCode();
                xh++;
            }
            kqKqbZb.setXh(xh);
            mapLit.add(JSON.parseObject(JSON.toJSONString(kqKqbZb), Map.class));
        }

        //模版所在位置
        String templateName = "员工考勤表上传模板1.xlsx";
        String serverPath = request.getSession().getServletContext().getRealPath("/");
        String ftlPath = serverPath + "ftl\\kh\\";
        String templateFileName = ftlPath + templateName;

        //文件名封装
        String fileName = month + "月-" + officeName + "-员工考勤表";
        response.setHeader("Content-disposition", "attachment;filename=" + String.valueOf(URLEncoder.encode(fileName, "UTF-8")) + ".xlsx");// 设置文件头编码格式
        response.setContentType("APPLICATION/OCTET-STREAM;charset=UTF-8");// 设置类型

        //定义合并规则
        List<Integer> mergeColumnIndex = ListUtils.newArrayList(0, 1, 2,35,36,37,38,39,40);//第几列所在行开始合并
        ExcelMergeStrategy loopMergeStrategy = new ExcelMergeStrategy(4, 2, mergeColumnIndex); // 从第4行开始,每隔2行合并,mergeColumnIndex需要合并行所在的列

        //开始填充
        ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(response.getOutputStream());
        excelWriterBuilder.registerWriteHandler(loopMergeStrategy);
        excelWriterBuilder.autoCloseStream(true);
        ExcelWriter excelWriter = excelWriterBuilder.withTemplate(templateFileName).build();
        WriteSheet writeSheet = EasyExcel.writerSheet().build();
        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
        excelWriter.fill(mapLit, fillConfig, writeSheet);
        Map<String, Object> map = MapUtils.newHashMap();
        map.put("officeName", officeName);
        map.put("year", year);
        map.put("month", month);
        map.put("ycqts", ycqts);
        excelWriter.fill(map, writeSheet);
        excelWriter.finish();
}

核心:从第0、1、2等列和第4行开始,每两行合并单元格

bash 复制代码
//定义合并规则
List<Integer> mergeColumnIndex = ListUtils.newArrayList(0, 1, 2,35,36,37,38,39,40);//第几列所在行开始合并
ExcelMergeStrategy loopMergeStrategy = new ExcelMergeStrategy(4, 2, mergeColumnIndex); // 从第4行开始,每隔2行合并,mergeColumnIndex需要合并行所在的列

4、新建合并策略类

bash 复制代码
package com.jeesite.modules.util;

import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;

/**
 * @Description EasyExcel 导出合并单元格
 */
@Slf4j
@Data
public class ExcelMergeStrategy implements RowWriteHandler {
    /*
     * 要合并的列 (下表也是从0开始)
     */
    private List<Integer> mergeColumnIndex;


    /*
     * 用第几行开始合并 ,默认为1,因为第0行是标题,EasyExcel 的默认也是
     */
    private int mergeBeginRowIndex = 1;

    /**
     * Each row
     */
    private int eachRow;

    private int columnExtend = 1;

    public ExcelMergeStrategy(int mergeBeginRowIndex, int eachRow, List<Integer> mergeColumnIndex) {
        this.mergeBeginRowIndex = mergeBeginRowIndex;
        this.eachRow = eachRow;
        this.mergeColumnIndex = mergeColumnIndex;
    }

    @Override
    public void afterRowDispose(RowWriteHandlerContext context) {
        if (context.getHead() || context.getRelativeRowIndex() == null) {
            return;
        }
        //当前行
        int curRowIndex = context.getRowIndex();
        //当前列
        if (curRowIndex > mergeBeginRowIndex) {
            if (context.getRelativeRowIndex() % eachRow == 0) {
                for (Integer columnIndex : mergeColumnIndex) {
                    CellRangeAddress cellRangeAddress = new CellRangeAddress(context.getRowIndex(),
                            context.getRowIndex() + eachRow - 1,
                            columnIndex, columnIndex + columnExtend - 1);
                    context.getWriteSheetHolder().getSheet().addMergedRegionUnsafe(cellRangeAddress);
                }
            }
        }
    }
}
相关推荐
珹洺1 小时前
Java-servlet(完结篇)过滤器乱码解决与监听器
java·运维·服务器·hive·servlet·jsp
小开不是小可爱2 小时前
leetcode_383. 赎金信_java
java·数据结构·算法·leetcode
Excel_easy2 小时前
表格开启聚光灯,查看数据不错行-Excel易用宝
excel
一个数据大开发2 小时前
如何将excel数据快速导入数据库
数据库·excel
野生胡萝卜2 小时前
处理Excel表不等长时间序列用tsfresh提取时序特征
python·excel·tsfresh
kill bert5 小时前
Java八股文背诵 第四天JVM
java·开发语言·jvm
z2014z5 小时前
Excel 自动执行全局宏
excel
你是理想8 小时前
wait 和notify ,notifyAll,sleep
java·开发语言·jvm
helloworld工程师8 小时前
【微服务】SpringBoot整合LangChain4j 操作AI大模型实战详解
java·eclipse·tomcat·maven
Java&Develop9 小时前
idea里面不能运行 node 命令 cmd 里面可以运行咋回事啊
java·ide·intellij-idea