java基于HuTool工具类ExcelWriter合并单元格

HuTool工具类ExcelWriter合并单元格

基于HuTool工具类ExcelWriter合并单元格并且使用 jdk1.8 lambda表达式
效果如下:
java基于HuTool工具类ExcelWriter合并单元格_第1张图片

  1. 创建注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by Intellij IDEA. Copyright@ zqy
 *
 * @Author: zqy
 * @Date: 2021/8/11
 * @Description: excel表头注解
 */

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface HeaderName {
    String value() default "";
}
  1. 创建实类
import java.io.Serializable;
import java.math.BigDecimal;

import cn.stylefeng.guns.modular.business.annotation.HeaderName;
import lombok.Data;

/**
 * Created by Intellij IDEA. Copyright@ zqy
 * 
 * @Author: zqy
 * @Date: 2021/8/2
 * @Description:
 */

/**
 * 材料实验
 */
@Data
public class MaterialsTestExcelVO implements Serializable {
    private static final long serialVersionUID = -3621354299691315539L;

    /**
     * 来源名称
     */
    @HeaderName("来源名称")
    private String msName;

    /**
     * 材料名称
     */
    @HeaderName("材料名称")
    private String mName;

    /**
     * 上端材料
     */
    @HeaderName("上端材料")
    private String materialSpringSide;

    /**
     * 下端材料
     */
    @HeaderName("下端材料")
    private String materialCarriageSide;

    /**
     * 温度
     */
    @HeaderName("温度")
    private String temp;

    /**
     * 相对湿度
     */
    @HeaderName("相对湿度")
    private String relattiveHumiduty;

    /**
     * 压力
     */
    @HeaderName("压力")
    private Integer normalForce;

    /**
     * 批次名称
     */
    @HeaderName("批次名称")
    private String batch;

    /**
     * 速度
     */
    @HeaderName("速度")
    private String relativeVelocity;

    /**
     * 啸叫率
     */
    @HeaderName("啸叫率")
    private BigDecimal groanGate;

    /**
     * 滑动摩擦力
     */
    @HeaderName("滑动摩擦力")
    private BigDecimal dynFrictForce;

    /**
     * 静摩擦力
     */
    @HeaderName("静摩擦力")
    private BigDecimal statFrictForce;

    /**
     * 测试时间
     */
    @HeaderName("测试时间")
    private String testTime;
}
  1. 代码逻辑
    1.查找数据库返回数据voList
    2.设置导出表头数据
    3.用lambda表达式获取字段分组数据;
    4.遍历数据,设置合并规则:
    5.将数据保存在list中
    6.ExcelWriter导出excel文件
  2. 代码:
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import lombok.SneakyThrows;
/***
 * @Description: 导出数据查询
 * @Author: zqy
 * @Date: 2021/8/12 14:56
 * @Param: dto response
 * @Return: void
 */
@SneakyThrows
@Override
public void export(MaterialsTestListSearchDTO dto, HttpServletResponse response) {
    List<MaterialsTestExcelVO> voList = testMapper.findExcelList(dto);
    downloadReport(voList, response);
}
/***
 * @Description: 下载数据
 * @Author: zqy
 * @Date: 2021/8/12 14:57
 * @Param: voList response
 * @Return: void
 */
public void downloadReport(List<MaterialsTestExcelVO> voList, HttpServletResponse response) throws IOException {
    // 定义基础数据
    List<String> rowHead = loadRowHead(MaterialsTestExcelVO.class);
    ExcelWriter writer = ExcelUtil.getBigWriter();
    // 写入标题
    writer.writeHeadRow(rowHead);
    // 获取导出数据
    List<List<Object>> rows = loadRowList(voList, writer);
    // 导出数据
    // 一次性写出内容,使用默认样式,强制输出标题
    writer.write(rows, true);
    // response为HttpServletResponse对象
    response.setContentType("application/vnd.ms-excel;charset=utf-8");
    // test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
    response.setHeader("Content-Disposition", "attachment;filename=file.xlsx");
    ServletOutputStream out = response.getOutputStream();
    writer.flush(out, true);
    // 此处记得关闭输出Servlet流
    IoUtil.close(out);
}
/***
 * @Description: 封装导出数据,并合并列
 * @Author: zqy
 * @Date: 2021/8/12 14:59
 * @Param: voList writer
 * @Return: java.util.List>
 */
private List<List<Object>> loadRowList(List<MaterialsTestExcelVO> voList, ExcelWriter writer) {
    // 定义启始行
    int index = 1;
    int index2 = 1;
    int index3 = 1;
    int index4 = 1;
    List<List<Object>> rows = new LinkedList<>();
    // 按照姓名分组数据汇总处理(lambda表达式,不了解可以百度)
    Map<String, List<MaterialsTestExcelVO>> msGroupMaps = voList.stream()
        .collect(Collectors.groupingBy(MaterialsTestExcelVO::getMsName, LinkedHashMap::new, Collectors.toList()));
    for (Map.Entry<String, List<MaterialsTestExcelVO>> listEntry : msGroupMaps.entrySet()) {
        List<MaterialsTestExcelVO> msList = listEntry.getValue();
        // 根据数据条数设置合并单元格信息
        if (msList.size() == 1) {// 一条数据不合并
            index = index + msList.size();
            index2 = index2 + msList.size();
            index3 = index3 + msList.size();
            index4 = index4 + msList.size();
        } else {
            // 规则编写
            writer.merge(index, index + msList.size() - 1, 0, 0, null, true);
            // 标题
            index = index + msList.size();
            // 按照编码进行分组
            Map<String, List<MaterialsTestExcelVO>> mGroupMaps = msList.stream().collect(
                Collectors.groupingBy(MaterialsTestExcelVO::getMName, LinkedHashMap::new, Collectors.toList()));
            for (Map.Entry<String, List<MaterialsTestExcelVO>> list2Entry : mGroupMaps.entrySet()) {
                List<MaterialsTestExcelVO> mList = list2Entry.getValue();
                // 根据数据条数设置合并单元格信息
                if (mList.size() == 1) {// 一条数据不合并
                    index2 = index2 + mList.size();
                    index3 = index3 + mList.size();
                    index4 = index4 + mList.size();
                } else {
                    // 规则编写
                    writer.merge(index2, index2 + mList.size() - 1, 1, 1, null, true);
                    index2 = index2 + mList.size();

                    // 按照编码进行分组
                    Map<String, List<MaterialsTestExcelVO>> ssGroupMaps =
                        mList.stream().collect(Collectors.groupingBy(MaterialsTestExcelVO::getMaterialSpringSide,
                            LinkedHashMap::new, Collectors.toList()));
                    for (Map.Entry<String, List<MaterialsTestExcelVO>> list3Entry : ssGroupMaps.entrySet()) {
                        List<MaterialsTestExcelVO> ssList = list3Entry.getValue();
                        // 根据数据条数设置合并单元格信息
                        if (ssList.size() == 1) {// 一条数据不合并
                            index3 = index3 + ssList.size();
                            index4 = index4 + ssList.size();
                        } else {
                            // 规则编写
                            writer.merge(index3, index3 + ssList.size() - 1, 2, 2, null, true);
                            index3 = index3 + ssList.size();

                            // 按照编码进行分组
                            Map<String,
                                List<MaterialsTestExcelVO>> csGroupMaps = ssList.stream()
                                    .collect(Collectors.groupingBy(MaterialsTestExcelVO::getMaterialCarriageSide,
                                        LinkedHashMap::new, Collectors.toList()));
                            for (Map.Entry<String, List<MaterialsTestExcelVO>> list4Entry : csGroupMaps
                                .entrySet()) {
                                List<MaterialsTestExcelVO> csList = list4Entry.getValue();
                                // 根据数据条数设置合并单元格信息
                                if (csList.size() == 1) {// 一条数据不合并
                                    index4 = index4 + csList.size();
                                } else {
                                    // 规则编写
                                    writer.merge(index4, index4 + csList.size() - 1, 3, 3, null, true);
                                    index4 = index4 + csList.size();
                                }
                            }
                        }
                    }
                }
            }
        }
        // 保存数据
        msList.forEach(sList -> {	
            List<Object> rowA = null;
            rowA = CollUtil.newArrayList(sList.getMsName(), sList.getMName(), sList.getMaterialSpringSide(),
                sList.getMaterialCarriageSide(), sList.getTemp(), sList.getRelattiveHumiduty(), sList.getBatch(),
                sList.getNormalForce(), sList.getRelativeVelocity(),  sList.getGroanGate(), sList.getDynFrictForce(), sList.getStatFrictForce(),
                sList.getTestTime());
            rows.add(rowA);
        });
    }
    return rows;
}
/***
 * @Description: 封装表头
 * @Author: zqy
 * @Date: 2021/8/12 15:00
 * @Param: albumClass 实体类class
 * @Return: java.util.List
 */
private List<String> loadRowHead(Class<?> albumClass) {
    List<String> rowHead = new ArrayList<>();
    // 获取 实体类 中所有的字段
    Field[] declaredFields = albumClass.getDeclaredFields();
    for (Field declaredField : declaredFields) {
        // 这里设置为 true 才可以访问到 实体类中的 private 字段
        declaredField.setAccessible(true);
        // 获取字段所对应的注解
        HeaderName annotation = declaredField.getAnnotation(HeaderName.class);
        if (null != annotation) {
            // 有注解 则 获取 注解的值(表头名称)
            rowHead.add(annotation.value());
        }
    }
    return rowHead;
}

借鉴地址

你可能感兴趣的:(java,java,excel,poi)