Java从零开始实现导出excel(二)

Java从零开始实现导出excel(二)

新人博主,随笔记录。主要还是通过自己日常工作积累,系统整理一些技术。希望能够节省更多人的时间,走出自己的路。

看了自己发的文章,可以帮助一些小伙伴很开心!!

简述:

上一篇文章主要用我个人觉得,效果很好的方法做excel的导出。但是那只是符合正常,简单的excel导出。可能很多小伙伴,会遇到一些复杂的样式的excel的导出。这一篇同样是用EasyExcel,主要是做一些数据格式复杂的excel,当然这一篇文章不包含复杂表头的excel导出

环境搭建:

这一篇的环境和上一篇我们共用一个。因为都是用EasyExcel这个包中的API,所以没必要换一个工程。还不明白的小伙伴可以去瞟一眼我的上一篇文章Java从零开始实现导出excel(一)

创建导出实体:

这里同样用的是上一篇的实体。不过有点改变,我将性别这一列放开了。
Java从零开始实现导出excel(二)_第1张图片
这里有个需要注意的地方,因为EasyExcel是通过实体中@ExcelProperty注解中的index去匹配excel中的列,所以当我们不使用模板时,index一定要是连续且有效的,否则我们生成的excel中会出现空白表头列的情况

例如:下面这图是我没有放开性别那个字段时导出的excel表头
Java从零开始实现导出excel(二)_第2张图片

导出Excel

导出方法:

 /**
     * 使用EasyExcel导出excel
     * @param response
     * @throws Exception
     */
    @GetMapping(value = "/exportExcel")
    public void exportExcel(HttpServletResponse response) throws Exception {
     
        response.setContentType("multipart/form-data");
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/octet-stream;charset=utf-8");
        LocalDate time = LocalDate.now();
        String fileName = URLDecoder.decode("easyExcel导出_" + time, "UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + new String(fileName.getBytes("gb2312"), "ISO8859-1") + ".xls" + "\"");
        OutputStream out = response.getOutputStream();
        List<Student> data = getData();
        Map<Integer,String[]> map = new HashMap<>();
        map.put(2,new String[]{
     "男","女"});//下拉导出
        ExcelUtil.exportBySelect(out,data,map);
        out.close();
    }


    //封装导出数据
    private List<Student> getData() {
     
        List<Student> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
     
            Student student = new Student();
            student.setName("测试学生姓名-" + i);
            student.setAge(i);
            student.setSex(i % 2 == 1 ? "男" : "女");
            student.setNum(111111L);
            student.setAddress("追晨始梦CSDN博客");
            list.add(student);
        }
        return list;
    }

工具类:

ExcelUtil

 /**
     * 功能描述: 导出数据到Excel
     * 

* 使用阿里easyPoi 自定义导出excel携带下拉框 * * @param out 输出 * @param list 需写入的数据 * @param mapDropDown 下拉框数据 */ public static void exportBySelect(OutputStream out, List<? extends BaseRowModel> list, Map<Integer, String[]> mapDropDown) { EasyExcelFactory.write(out, list.get(0).getClass()).registerWriteHandler(new EasyExcelSheetSelectUtils(mapDropDown)).sheet().doWrite(list); }

这个公共方法中,我们需要去调用registerWriteHandler方法:将我们创建的自定义拦截器放入其中。

这个拦截器是我们这篇文章的重点——直接代码看

EasyExcelSheetSelectUtils


package com.example.demo;


import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;

import java.util.Map;

/**
 * 自定义设置excel样式
 */
public class EasyExcelSheetSelectUtils implements SheetWriteHandler {
     

    //第0列开始 设置某列的下拉内容
    private Map<Integer,String[]> mapDropDown;

    public EasyExcelSheetSelectUtils(Map<Integer, String[]> mapDropDown) {
     
        this.mapDropDown = mapDropDown;
    }

    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
     

    }

    /**
     * 自定义设置excel样式
     * @param writeWorkbookHolder
     * @param writeSheetHolder
     */
    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
     

        //获取sheet页
        Sheet sheet = writeSheetHolder.getSheet();
        ///开始设置下拉框 //设置下拉框
        DataValidationHelper helper = sheet.getDataValidationHelper();
        for (Map.Entry<Integer, String[]> entry : mapDropDown.entrySet()) {
     
            /***起始行、终止行、起始列、终止列**/
            CellRangeAddressList addressList = new CellRangeAddressList(1, 1000, entry.getKey(), entry.getKey());
            /***设置下拉框数据**/
            DataValidationConstraint constraint = helper.createExplicitListConstraint(entry.getValue());
            DataValidation dataValidation = helper.createValidation(constraint, addressList);
            /***处理Excel兼容性问题**/
            if (dataValidation instanceof XSSFDataValidation) {
     
                dataValidation.setSuppressDropDownArrow(true);
                dataValidation.setShowErrorBox(true);
            } else {
     
                dataValidation.setSuppressDropDownArrow(false);
            }
            sheet.addValidationData(dataValidation);
        }
        //合并单元格
        sheet.addMergedRegion(new CellRangeAddress(1, 2, 0, 0));
    }
}

这个里面我写了两个常见的案例:

  1. 下拉框
  2. 合并单元格

当然了,可能小伙伴们在实际工作中可能有很多不一样的需求,看完我的两个案例的实现,相信你所需要的样式,都可以自己实现。

1. 下拉框

这个功能可能模板导出时候,会更加方便一点。这里我觉得主要是一个思想

首先我们看实现的过程
Java从零开始实现导出excel(二)_第3张图片
我们自定义的拦截器一定要继承SheetWriteHandler这个接口
这个接口中有两个虚函数:
Java从零开始实现导出excel(二)_第4张图片
我们这里一般会用到下面那个函数 :afterSheetCreate

我们在自定义的拦截器中定义了一个私有属性mapDropDown,用来装下拉框的参数。用一个有参构造将我们需要的数据传进来
key: 表示第几列需要加入下拉框
value: 表示加入下拉框的值

Java从零开始实现导出excel(二)_第5张图片

2.合并单元格

这里我是只做了个案例,将excel表格中的第一列的第一行和第二行进行合并
在这里插入图片描述

导出文件效果:

Java从零开始实现导出excel(二)_第6张图片

这里面,最重要的一步是,我们能获取到sheet页

在这里插入图片描述有了这个sheet页的对象,那其他自定义功能的效果,小伙伴们可以发挥自己的技术,根据自己的需求完成excel导出!

源码链接

官方文档地址

你可能感兴趣的:(Excel文件导出,java,spring,后端,流处理)