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

一、最终效果

在这里插入图片描述

二、制作模版

1、制作填充模版
在这里插入图片描述
模版在代码中保存的位置
在这里插入图片描述

2、Controller

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

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

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行开始,每两行合并单元格

//定义合并规则
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、新建合并策略类

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);
                }
            }
        }
    }
}
EasyExcel中,使用ExcelWriter基于Excel模板填充时,可以使用注解`@ExcelProperty`来指定数据在Excel模板中的位置,并使用`@ContentRowHeight`、`@HeadRowHeight`、`@HeadStyle`、`@ContentStyle`等注解来设置单元格的样式和格式。 而对于合并单元格,可以使用`@ContentLoopMerge`注解来实现。具体步骤如下: 1.在Excel模板中设置需要合并的单元格。例如,我们需要将第2列的数据按照第1列的值进行合并,则可以在第1列的单元格中设置`@ContentLoopMerge(name = "name")`注解来指定需要合并的单元格。如下所示: ``` | 姓名 | 年龄 | 性别 | |------|------|------| | A | 20 | 男 | | A | 25 | 女 | | B | 30 | 男 | | B | 35 | 女 | ``` 2.在实体类中使用`@ExcelProperty`注解来指定数据在Excel模板中的位置。同时,使用`@ContentLoopMerge(name = "name")`注解来指定需要合并的单元格。如下所示: ```java public class User { @ExcelProperty(value = "姓名", index = 0) @ContentLoopMerge(name = "name") private String name; @ExcelProperty(value = "年龄", index = 1) private Integer age; @ExcelProperty(value = "性别", index = 2) private String gender; // getter和setter方法省略 } ``` 3.在代码中使用`ExcelWriter`对象来填充数据,使用`FillConfig`对象来设置`@ContentLoopMerge`注解的参数。如下所示: ```java // 加载Excel模板 InputStream templateInputStream = new FileInputStream("template.xlsx"); Template template = TemplateUtil.loadTemplate(templateInputStream); // 创建ExcelWriter对象 ExcelWriter writer = EasyExcel.write(outputStream).withTemplate(template).build(); // 设置FillConfig对象 FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build(); // 填充数据 List<User> userList = getUserList(); writer.fill(userList, fillConfig, new Sheet(0)); // 关闭ExcelWriter对象 writer.finish(); ``` 在上面的示例中,我们首先加载Excel模板,然后创建`ExcelWriter`对象,设置`FillConfig`对象并填充数据。其中,`forceNewRow`参数表示是否强制创建新的行,`Sheet`对象表示填充数据的Sheet页。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值