使用easyExcel 导出文件并合并相同内容的单元格-导出下拉模板-数据有效性校验

首先看下效果:

在这里插入图片描述

一、导入依赖

		<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.3</version>
        </dependency>

二、准备工具类

1.操作的工具类
package com.yuncheng.utils.excel;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
import com.yuncheng.utils.excel.handler.AutoWidthHandler;
import com.yuncheng.utils.excel.handler.SelectSheetWriteHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.*;
/**
 * @Description: 动态excel工具类
 * @Author: ChenH
 * @Date: 2024/7/23 10:50
 */

@Component
@Slf4j
public class  DynamicExcelUtils {
   
   

    /**
     * 动态excel模板下载
     * @param response  响应
     * @param title     大标题说明,多行使用转义符\n换行
     * @param names     列集合
     * @param fieldEn   列英文名称
     * @param selectMap 下拉框
     * @param fileName  自定义文件名称
     * @param sheetName 自定义sheet页名称
     */
    public void excelDownloadLink(HttpServletResponse response, String title,List<String> names, List<String> fieldEn ,List list ,Map<Integer,
            List<String>> selectMap,String sheetName, String fileName) {
   
   
        try {
   
   
            //设置表格示例数据的值
            List<List<String>> datas = setData(list,fieldEn);
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
            response.setCharacterEncoding("UTF-8");
            EasyExcel.write(response.getOutputStream())
                    .excelType(ExcelTypeEnum.XLSX)
                    .head(head(CollectionUtil.isNotEmpty(names) ? names.toArray(new String[0]) : new String[0], title))
                    //开启内存模式才能使用动态设置标题样式
                    .inMemory(true)
                    .registerWriteHandler(new TitleStyleUtils(names))
                    .registerWriteHandler(new SelectSheetWriteHandler(selectMap))
                    .registerWriteHandler(new SimpleColumnWidthStyleStrategy(25))
                    .sheet(sheetName)
                    .doWrite(CollectionUtil.isNotEmpty(datas) ? datas:new ArrayList());
        } catch (IOException e) {
   
   
            e.printStackTrace();
            response.reset();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json");
            try {
   
   
                response.getWriter().println("打印失败");
            } catch (IOException ex) {
   
   
                ex.printStackTrace();
            }
        }
    }


    /**
     * 动态excel数据导出
     * @param response 响应
     * @param fileName  自定义文件名称
     * @param sheetName 自定义sheet页名称
     * @param list     数据集合
     */
    public void excelExportData(HttpServletResponse response,List<String> names,List<String> fieldEn,List list ,String sheetName, String fileName){
   
   
        try {
   
   
            //设置返回数据的值跟动态列一一对应
            List<List<String>> datas = setData(list,fieldEn);
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
            response.setCharacterEncoding("UTF-8");
            EasyExcel.write(response.getOutputStream())
                    .excelType(ExcelTypeEnum.XLSX)
                    .head(headData(CollectionUtil.isNotEmpty(names) ? names.toArray(new String[0]) : new String[0]))
                    .registerWriteHandler(new AutoWidthHandler())
                    .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 25, (short) 25))
                    .sheet(sheetName)
                    .doWrite(CollectionUtil.isNotEmpty(datas) ? datas:new ArrayList());

        } catch (IOException e) {
   
   
            e.printStackTrace();
            response.reset();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json");
            try {
   
   
                response.getWriter().println("打印失败");
            } catch (IOException ex) {
   
   
                ex.printStackTrace();
            }
        }
    }
    /**
     * 动态excel数据导出
     * @param response 响应
     * @param fileName  自定义文件名称
     * @param sheetName 自定义sheet页名称
     * @param list     数据集合
     */
    public void excelExportData(HttpServletResponse response, List<String> names, List list, String sheetName, String fileName){
   
   
        try {
   
   
            //设置返回数据的值跟动态列一一对应
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
            response.setCharacterEncoding("UTF-8");
            EasyExcel.write(response.getOutputStream())
                    .excelType(ExcelTypeEnum.XLSX)
                    //.head(head(CollectionUtil.isNotEmpty(names) ? names.toArray(new String[0]) : new String[0], title))
                    .head(headData(CollectionUtil.isNotEmpty(names) ? names.toArray(new String[0]) : new String[0]))
                    .registerWriteHandler(new AutoWidthHandler())
                    .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 25, (short) 25))
                    .sheet(sheetName)
                    .doWrite(CollectionUtil.isNotEmpty(list) ? list:new ArrayList());
        } catch (IOException e) {
   
   
            e.printStackTrace();
            response.reset();
            response.setCharacterEncoding(
### 使用 EasyExcel 导出带有多层级合并单元的 Excel 文件 EasyExcel 是阿里巴巴开源的一个轻量级 Java 库,专注于简化 Excel 的读取和写入操作。它支持高效处理大文件提供了灵活的扩展机制来满足复杂需求。 以下是关于如何使用 EasyExcel 实现导出带有合并多层级单元格的 Excel 文件的具体方法: #### 1. 配置 Maven 或 Gradle 依赖 首先,在项目的 `pom.xml` 中引入 EasyExcel 的依赖项: ```xml <dependency> <groupId>com.alibaba.excel</groupId> <artifactId>easyexcel</artifactId> <version>3.0.5</version> </dependency> ``` 如果使用的是 Gradle,则可以这样配置: ```gradle implementation 'com.alibaba.excel:easyexcel:3.0.5' ``` --- #### 2. 创建实体类 为了方便映射到 Excel 表头字段,创建一个简单的 POJO 类作为数据模型。 ```java public class DemoData { private String name; private Integer age; public DemoData(String name, Integer age) { this.name = name; this.age = age; } @Override public String toString() { return "DemoData{" + "name='" + name + '\'' + ", age=" + age + '}'; } } ``` --- #### 3. 编写自定义监听器或处理器 通过继承 `WriteHandler` 接口来自定义单元格合并逻辑。下面是一个示例代码片段,展示如何实现多层级单元格合并。 ```java import com.alibaba.excel.write.handler.WriteHandler; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress; import java.util.List; public class CustomMergeStrategy implements WriteHandler { /** * 自动合并指定范围内的单元格 */ @Override public void sheet(int sheetNo, Sheet sheet) { // 定义需要合并的区域(例如第1列的第2至第4行) List<CellRangeAddress> mergeRegions = List.of( new CellRangeAddress(1, 3, 0, 0), // 第1列的第2至第4行 new CellRangeAddress(1, 2, 1, 2) // 第2、3列的第2至第3行 ); for (CellRangeAddress region : mergeRegions) { sheet.addMergedRegion(region); } } @Override public void row(int rowNum, Row row) {} @Override public void cell(Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {} } ``` 上述代码中,`sheet()` 方法用于设置多个合并区域。这里展示了两个例子: - 将第1列的第2至第4行进行合并- 将第2、3列的第2至第3行进行跨列合并--- #### 4. 主程序编写 最后一步是在主程序中调用 EasyExcel 提供的方法完成导出操作。 ```java import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.metadata.WriteSheet; import java.util.ArrayList; import java.util.List; public class MainExportExample { public static void main(String[] args) { // 准备测试数据 List<DemoData> data = new ArrayList<>(); data.add(new DemoData("Alice", 25)); data.add(new DemoData("Bob", 30)); data.add(new DemoData("Charlie", 35)); // 设置输出路径 String fileName = "./output.xlsx"; try ( // 初始化 writer 对象 ExcelWriter excelWriter = EasyExcel.write(fileName).build() ) { // 添加工作表 WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").head(DemoData.class).build(); // 注册自定义合并策略 excelWriter.registerWriteHandler(new CustomMergeStrategy()); // 执行写入操作 excelWriter.write(data, writeSheet); } catch (Exception e) { System.out.println(e.getMessage()); } } } ``` 此代码完成了以下几件事情: - 构造了一个包含三行记录的数据集; - 调用了 `EasyExcel.write()` 方法初始化 Writer 注册了自定义合并策略; - 最终将数据写入名为 `"./output.xlsx"` 的文件中[^1]。 --- #### 注意事项 1. **性能优化**:对于超大数据量场景,建议启用分页模式或者流式写法以减少内存消耗。 2. **样式调整**:可以通过覆盖默认样式进一步美化表外观,比如字体大小、背景颜色等。 3. **异常捕获**:在生产环境中应增加更完善的错误日志记录以便排查问题。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值