easypoi Excel的导入导出(完整示例)

码字不易,还请各位大爷们点赞收藏加关注喔~😘💕

文章目录

前言

        easypoi官方文档

一、准备工作,导包

二、导入

2.1  无校验结果导入

2.2  有校验结果的导入

2.3  大数据导入

三、导出

3.1  简单导出

3.2  模板导出

3.3  多 sheet 的模板导出

3.4  大数据导出

方法一:先查出数据,再导

方法二:在导入的方法中查数据


前言

easypoi官方文档

旧地址:EasyPoi教程_V1.0
新地址:1. 前言 - Powered by MinDoc

一、准备工作,导包

 easypoi 3.x 的版本和 4.x 的版本有的地方有略微的不同,但最后实现的效果都差不多,这里我用的是 4.4.0 的

        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>xerces</groupId>
            <artifactId>xercesImpl</artifactId>
            <version>2.12.2</version>
        </dependency>

easypoi-annotation :基础注解包,作用与实体对象上,拆分后方便maven多工程的依赖管理

easypoi-base :导入导出的工具包,可以完成Excel导出,导入,Word的导出,Excel的导出功能

easypoi-web :耦合了spring-mvc 基于AbstractView,极大的简化spring-mvc下的导出功能

xercesImpl : 支持通过 Sax 方式的大数据量导入


二、导入

2.1  无校验结果导入

关键代码: ExcelImportUtil.importExcel(InputStream inputstream, Class<?> pojoClass,
ImportParams params);

inputstream: 数据源输入流,也就是文件输入流

pojoClass:    接收文件类型的类

params:        导入参数,直接 new ImportParams()

        1. 准备一张数据表,如:

        2.定义对应的对象,顺序可以和表中不一样,属性也可以没有,但是需要赋值的属性它的 @Excel(name="") 要和表中字段一一对应上:

package web_test.model;

import cn.afterturn.easypoi.excel.annotation.Excel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import web_test.model.onecodeend.ExcelVerifyInfo;

import java.util.Date;

/**
 * @author shenlongdaxia
 */
@EqualsAndHashCode(callSuper = false)
@Data
public class ImportEntity {

    @Excel(name = "序号")
    private String serialNum;

    @Excel(name = "姓名")
    private String name;

    @Excel(name = "性别", replace = {"男_true", "女_false"})
    private Boolean sex;

    @Excel(name = "电话")
    private String phone;

    @Excel(name = "购买时间", format = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+08")
    private Date buyTime;

    @Excel(name = "住址")
    private String address;

    @Excel(name = "水果", groupName = "订单类别")
    private String fruitsName;

    @Excel(name = "蔬菜")
    private String vegetableName;

}

replace:  会将 "_" 前的内容替换成后面的 

format :  会解析Excel 中的时间内容,但必须和 指定解析的格式一样,结合 @JsonFormat 注解,就可以将时间解析为标准格式了

groupName:会自动识别出Excel 水平合并的单元格,直到出现下一个 groupName 为止

 controller 

@PostMapping("/importExcel")
    public List<ImportEntity> importExcel(@RequestPart("file") MultipartFile file){
        return apiTestService.importExcel(file);
    }

serviceImpl:

@Override
    public List<ImportEntity> importExcel(MultipartFile file) {
        try {
            ImportParams params = new ImportParams();
            params.setHeadRows(2);

            List<ImportEntity> list = ExcelImportUtil.importExcel(file.getInputStream(), ImportEntity.class, params);
            return list;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

结果:


2.2  有校验结果的导入

关键代码: ExcelImportUtil.importExcelMore(InputStream inputstream, Class<?> pojoClass,
ImportParams params);

inputstream: 数据源输入流,也就是文件输入流

pojoClass:    接收文件内容的类的字节码类型

params:        导入参数,直接 new ImportParams()

注意导入的方法是 importExcelMore ,比 无校验的导入 多了一个 More

        1.  还是这张表,这里我们把导入的实体类 ImportEntity 改造一下,使其可以额外记录一些错误的信息

package web_test.model;

import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.handler.inter.IExcelDataModel;
import cn.afterturn.easypoi.handler.inter.IExcelModel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.Date;

/**
 * @author shenlongdaxia
 */
@EqualsAndHashCode(callSuper = false)
@Data
public class ImportEntity implements IExcelModel, IExcelDataModel {

    @Excel(name = "序号")
    private String serialNum;

    @Excel(name = "姓名")
    private String name;

    @Excel(name = "性别", replace = {"男_true", "女_false"})
    private Boolean sex;

    @Excel(name = "电话")
    private String phone;

    @Excel(name = "购买时间", format = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+08")
    private Date buyTime;

    @Excel(name = "住址")
    private String address;

    @Excel(name = "水果", groupName = "订单类别")
    private String fruitsName;

    @Excel(name = "蔬菜")
    private String vegetableName;

    /**
     * 记录当前是第几行
     */
    private Integer rowNum;

    /**
     * 记录当前行在校验时存在的错误信息
     */
    private String errorMsg;

    @Override
    public Integer getRowNum() {
        return this.rowNum;
    }

    @Override
    public void setRowNum(Integer integer) {
        this.rowNum = integer;
    }

    @Override
    public String getErrorMsg() {
        return this.errorMsg;
    }

    @Override
    public void setErrorMsg(String s) {
        this.errorMsg = s;
    }
}

  controller:

@PostMapping("/importExcel")
    public void importExcel(@RequestPart("file") MultipartFile file){
        apiTestService.importExcel(file);
    }

   serviceImpl:

先注入 校验处理器:

@Service
public class ApiTestServiceImpl implements IApiTestService {

    @Resource
    ExcelVerifyHandler handler;


    @Override
    public void importExcel(MultipartFile file) {
        try {
            ImportParams params = new ImportParams();
            params.setHeadRows(2);
            // 设置是否需要校验为 true,开启校验
            params.setNeedVerify(true);
            // 设置校验处理器,我们将校验的内容放在这个里面
            params.setVerifyHandler(new ExcelVerifyHandler());

            // 这里的导入结果里面既有检验失败的数据,也有校验成功的数据
            ExcelImportResult<ImportEntity> importResult = ExcelImportUtil.importExcelMore(file.getInputStream(), ImportEntity.class, params);
            // 获取校验成功的数据
            List<ImportEntity> list = importResult.getList();

            // 我们来打印信息校验成功的数据看看
            list.forEach(System.out::println);

            // 获取校验失败的数据
            List<ImportEntity> failList = importResult.getFailList();
            // 我们来打印信息校验失败的数据看看
            if (failList != null){
                failList.forEach(System.out::println);
                // 再来看看检验失败数据的错误信息
                String errorMsg = failList.stream().map(ImportEntity::getErrorMsg).collect(Collectors.joining(","));
                System.out.println("错误原因:" + errorMsg);
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
   
}

ExcelVerifyHandler :

package web_test.handler;

import cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHandlerResult;
import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;
import web_test.model.ImportEntity;

/**
 * @author shenlongdaxia
 */
public class ExcelVerifyHandler implements IExcelVerifyHandler<ImportEntity> {

    /**
     * 具体校验的方法,它会每一行每一行的校验
     *
     * @param entity
     * @return ExcelVerifyHandlerResult 
     */
    @Override
    public ExcelVerifyHandlerResult verifyHandler(ImportEntity entity) {
        System.out.println("正在校验第 " + entity.getRowNum() + " 行");
        if (entity.getAddress() == null) {
            return new ExcelVerifyHandlerResult(false, "第 " + entity.getRowNum() + " 行地址不能为空");
        }
        return new ExcelVerifyHandlerResult(true);
    }
}

把 Excel 加点错误数据:

结果:

这样直接把 行号、错误信息和实体类 写在一起的话,每条数据都会带着这俩多余的信息,所以我们可以把这两个提出去,让实体类 去继承,最后我们得到的数据就没有多余的内容了:

ImportEntity:

package web_test.model;

import cn.afterturn.easypoi.excel.annotation.Excel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import web_test.model.onecodeend.ExcelVerifyInfo;

import java.util.Date;

/**
 * @author shenlongdaxia
 */
@EqualsAndHashCode(callSuper = false)
@Data
public class ImportEntity extends ExcelVerifyInfo {

    @Excel(name = "序号")
    private String serialNum;

    @Excel(name = "姓名")
    private String name;

    @Excel(name = "性别", replace = {"男_true", "女_false"})
    private Boolean sex;

    @Excel(name = "电话")
    private String phone;

    @Excel(name = "购买时间", format = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+08")
    private Date buyTime;

    @Excel(name = "住址")
    private String address;

    @Excel(name = "水果", groupName = "订单类别")
    private String fruitsName;

    @Excel(name = "蔬菜")
    private String vegetableName;

}

 ExcelVerifyInfo :

package web_test.model;

import cn.afterturn.easypoi.handler.inter.IExcelDataModel;
import cn.afterturn.easypoi.handler.inter.IExcelModel;
import lombok.Data;

/**
 * Excel校验基类
 *
 * @author shenlongdaxia
 */
@Data
public class ExcelVerifyInfo implements IExcelModel, IExcelDataModel {

    private Integer rowNum;

    private String errorMsg;

    @Override
    public String getErrorMsg() {
        return errorMsg;
    }

    @Override
    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    @Override
    public Integer getRowNum() {
        return this.rowNum;
    }

    @Override
    public void setRowNum(Integer rowNum) {
        this.rowNum = rowNum;
    }
}

结果:

 雅~ 😎


2.3  大数据导入

关键代码:void  ExcelImportUtil.importExcelBySax(InputStream inputstream, Class<?> pojoClass, ImportParams params, IReadHandler handler);

注意!! 通过 Sax 方式导入是没有返回值的,数据的保存在 IReadHandler 参数里面进行

inputstream: 传入文件的输入流

pojoClass:接收文件内容的实体类的字节码类型

params: 导入参数

handler: 接口自定义处理类,里面有俩个方法,一个是 handler(),这里面就是每条数据要做什么事情,另一个是 doAfterAll(),这里面就是所有数据处理完之后要做什么事情。直接开 new

表: 塞了 100 条数据

实体类:

因为所有的导入数据的处理都在 IReadHandler 中进行,所有我们的实体类就可以不用实现校验了

package web_test.model;

import cn.afterturn.easypoi.excel.annotation.Excel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import web_test.model.onecodeend.ExcelVerifyInfo;

import java.util.Date;

/**
 * @author shenlongdaxia
 */
@EqualsAndHashCode(callSuper = false)
@Data
public class ImportEntity {

    @Excel(name = "序号")
    private String serialNum;

    @Excel(name = "姓名")
    private String name;

    @Excel(name = "性别", replace = {"男_true", "女_false"})
    private Boolean sex;

    @Excel(name = "电话")
    private String phone;

    @Excel(name = "购买时间", format = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+08")
    private Date buyTime;

    @Excel(name = "住址")
    private String address;

    @Excel(name = "水果", groupName = "订单类别")
    private String fruitsName;

    @Excel(name = "蔬菜")
    private String vegetableName;

}

controller:

@PostMapping("/importExcel")
    public void importExcel(@RequestPart("file") MultipartFile file){
        apiTestService.importExcel(file);
    }

serviceImpl:

    @Override
    public void importExcel(MultipartFile file) {
        try {
            ImportParams params = new ImportParams();
            params.setHeadRows(2);

            // 弄一个开始时间和结束时间,看看最后的执行效果怎么样
            long startTime = new Date().getTime();
            final long[] endTime = new long[1];

            // 创建一个数组来保存导入的数据
            LinkedList<ImportEntity> entities = new LinkedList<>();

            ExcelImportUtil.importExcelBySax(file.getInputStream(), ImportEntity.class, params, new IReadHandler<ImportEntity>() {
                @Override
                public void handler(ImportEntity entity) {
                    // 在这里处理每条数据,因为这种导入没有返回值,所有我们可以在这里进行校验,并把通过的塞进 list 中
                    if (entity.getAddress() != null) {
                        entities.add(entity);
                    }
                }

                @Override
                public void doAfterAll() {
                    // 里面的变量默认是数组的
                    endTime[0] = new Date().getTime();
                }
            });

            // 输出下 list 的数量
            System.out.println("导入的数据共有:" + entities.size() + "条");
            // 计算一下导入的时间为
            System.out.println("导入时间共计:" + (endTime[0] - startTime) + " ms");

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

结果:


三、导出

3.1  简单导出

关键代码:ExcelExportUtil.exportExcel(ExportParams entity, Class<?> pojoClass, Collection<?> dataSet);

entity:        导入参数,常用的就是传入 title 和 sheetName,直接开 new

pojoClass:        导出文件内容的类的字节码类型

dataSet:        需要导出的数据

表:

导出实体类:

package web_test.model;

import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.util.Date;

/**
 * @author shenlongdaxia
 */
@EqualsAndHashCode(callSuper = false)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ExportEntity {

    @Excel(name = "序号", needMerge = true)
    private Integer serialNum;

    @Excel(name = "姓名", needMerge = true)
    private String name;

    @Excel(name = "性别", needMerge = true, replace = {"男_true", "女_false"}, width = 15.0)
    private Boolean sex;

    @Excel(name = "电话", needMerge = true)
    private String phone;

    @Excel(name = "购买时间", format = "yyyy-MM-dd HH:mm:ss", needMerge = true, width = 20.0)
    private Date buyTime;

    @Excel(name = "住址", needMerge = true, width = 15.0)
    private String address;

    @Excel(name = "水果", groupName = "订单类别", width = 15.0)
    private String fruitsName;

    @Excel(name = "蔬菜", groupName = "订单类别", width = 15.0)
    private String vegetableName;

}

controller:

    @GetMapping(value = "/exportExcelTest")
    public void exportExcelTest(HttpServletResponse response) {
        apiTestService.exportExcelTest(response);
    }

serviceImpl:

@Override
    public void exportExcelTest(HttpServletResponse response) {

        LinkedList<ExportEntity> entities = new LinkedList<>();
        
        // 先造一些数据
        for (int i = 1; i < 101; i++) {
            ExportEntity entity = new ExportEntity(i, "zs" + i, i % 2 == 0, "134" + i, new Date(),
                    "汤臣" + i + "品", i + "个苹果", i + "个西红柿");
            entities.add(entity);
        }

        // 导出,并获取工作簿
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(null, "简单导出测试表"), ExportEntity.class, entities);
        
        // 输出
        responseWorkbook(response, workbook, "简单导出.xlsx");
    }

    /**
     * 导出 Excel
     *
     * @param response
     * @param workbook
     * @param fileName
     */
    private static void responseWorkbook(HttpServletResponse response, Workbook workbook, String fileName) {

        try {
            response.setHeader("Content-disposition", "attachment;" + "filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/octet-stream; charset=UTF-8");
            workbook.write(response.getOutputStream());

            workbook.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

结果:

简单导出的关键在于实体类的设置,需要根据表头去一点一点的去调整,贼拉麻烦,所以就有了模板导出


3.2  模板导出

关键代码:ExcelExportUtil.exportExcel(TemplateExportParams params, Map<String, Object> map);

params:模板参数,直接开 new,第一个参数是模板文件的位置,第二个参数是在第几个sheet 中导出,位置从 0 开始

map: 导出的内容数据

导出模板:

 位置:

导出实体类:

package web_test.model;

import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.util.Date;

/**
 * @author shenlongdaxia
 */
@EqualsAndHashCode(callSuper = false)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ExportEntity {

    private Integer serialNum;

    private String name;

    private Boolean sex;

    private String phone;

    private Date buyTime;

    private String address;

    private String fruitsName;

    private String vegetableName;

}

serviceImpl:

@Override
    public void exportExcelTest(HttpServletResponse response) {

        // ================= 准备环节 ==================

        LinkedList<ExportEntity> entities = new LinkedList<>();
        // 先造一些数据
        for (int i = 1; i < 101; i++) {
            ExportEntity entity = new ExportEntity(i, "zs" + i, i % 2 == 0, "134" + i, new Date(),
                    "模板之汤臣" + i + "品", i + "个苹果", i + "个西红柿");
            entities.add(entity);
        }

        //  ================= 主要环节 ==================

        // 获取模板数据
        TemplateExportParams params = new TemplateExportParams("test/导出模板.xlsx", 0);

        ArrayList<Map<String, Object>> list = new ArrayList<>();

        for (ExportEntity entity : entities) {
        // 塞入具体数据,工具类用的是 hutool 包
            list.add(BeanUtil.beanToMap(entity));
        }

        HashMap<String, Object> workbookNeedMap = new HashMap<>();
        workbookNeedMap.put("maps", list);

        // 导出,并获取工作簿
        Workbook workbook = ExcelExportUtil.exportExcel(params, workbookNeedMap);

        // ================= 结束输出 ==================
        // 输出
        responseWorkbook(response, workbook, "模板导出.xlsx");
    }

    /**
     * 导出 Excel
     *
     * @param response
     * @param workbook
     * @param fileName
     */
    private static void responseWorkbook(HttpServletResponse response, Workbook workbook, String fileName) {

        try {
            response.setHeader("Content-disposition", "attachment;" + "filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/octet-stream; charset=UTF-8");
            workbook.write(response.getOutputStream());

            workbook.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

结果:

可以发现,模板导出的特点就是只填充表的数据表的格式根本就不用管,甚至连实体类都是干净的一毛不拔,贼拉方便。里面的数据我们也可以在塞数据时进行微调:

//  ================= 主要环节 ==================

        // 获取模板数据
        TemplateExportParams params = new TemplateExportParams("test/导出模板.xlsx", 0);

        ArrayList<Map<String, Object>> list = new ArrayList<>();

        for (ExportEntity entity : entities) {
            // 塞入具体数据,工具类都是 hutool 包提供
            Map<String, Object> map = BeanUtil.beanToMap(entity);
            map.put("sex", entity.getSex() ? "男" : "女");
            map.put("buyTime", DateUtil.format(entity.getBuyTime(), "yyyy-MM-dd HH:mm:ss"));
            list.add(map);
        }

        HashMap<String, Object> workbookNeedMap = new HashMap<>();
        workbookNeedMap.put("maps", list);

        // 导出,并获取工作簿
        Workbook workbook = ExcelExportUtil.exportExcel(params, workbookNeedMap);

其他的都不用变,结果:

完美~😎


3.3  多 sheet 的模板导出

关键代码:ExcelExportUtil.exportExcel(TemplateExportParams params, Map<String, Object> map);

params:模板参数,将第二个 sheet 参数设置为 true

map: 导出的内容数据,将多个 sheet 的 map 都添加进这里面

和 模板导出不同的地方就是将 导入的模板参数的 第二个设置为 true,然后不同的 sheet 表其表达式的 maps 设置成不同的参数就可以了。

表:

Role 实体类:

package web_test.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.util.Date;

/**
 * @author shenlongdaxia
 */
@EqualsAndHashCode(callSuper = false)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RoleEntity {

    private Integer id;

    private String name;

    private String type;
}

serviceImpl:

 @Override
    public void exportExcelTest(HttpServletResponse response) {

        // ================= 准备环节 ==================

        LinkedList<ExportEntity> entities = new LinkedList<>();
        LinkedList<RoleEntity> roles = new LinkedList<>();
        // 先造一些数据
        for (int i = 1; i < 101; i++) {
            ExportEntity entity = new ExportEntity(i, "zs" + i, i % 2 == 0, "134" + i, new Date(),
                    "模板之汤臣" + i + "品", i + "个苹果", i + "个西红柿");
            entities.add(entity);

            roles.add(new RoleEntity(i, "角色" + i, "类型" + i));
        }

        //  ================= 主要环节 ==================

        // 获取模板数据
        TemplateExportParams params = new TemplateExportParams("test/导出模板.xlsx", true);

        // 塞 sheet1 表的数据
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        for (ExportEntity entity : entities) {
            // 塞入具体数据,工具类都是 hutool 包提供
            Map<String, Object> map = BeanUtil.beanToMap(entity);
            map.put("sex", entity.getSex() ? "男" : "女");
            map.put("buyTime", DateUtil.format(entity.getBuyTime(), "yyyy-MM-dd HH:mm:ss"));
            list.add(map);
        }

        // 塞 sheet2 表的数据
        ArrayList<Map<String, Object>> roleList = new ArrayList<>();
        for (RoleEntity role : roles) {
            list.add(BeanUtil.beanToMap(role));
        }

        HashMap<String, Object> workbookNeedMap = new HashMap<>();
        workbookNeedMap.put("maps", list);
        workbookNeedMap.put("aa", roleList);

        // 导出,并获取工作簿
        Workbook workbook = ExcelExportUtil.exportExcel(params, workbookNeedMap);

        // ================= 结束输出 ==================
        // 输出
        responseWorkbook(response, workbook, "模板导出.xlsx");
    }

    /**
     * 导出 Excel
     *
     * @param response
     * @param workbook
     * @param fileName
     */
    private static void responseWorkbook(HttpServletResponse response, Workbook workbook, String fileName) {

        try {
            response.setHeader("Content-disposition", "attachment;" + "filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/octet-stream; charset=UTF-8");
            workbook.write(response.getOutputStream());

            workbook.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

结果:

真是妙~~啊


3.4  大数据导出

方法一:先查出数据,再导

核心代码:ExcelExportUtil.exportBigExcel(ExportParams entity, List<ExcelExportEntity> excelParams);

entity:导出参数,直接开 new

excelParams: 导出数据

这种方法比较简单,他的特点是,先把数据查出来保存在 List 中,然后根据实体类的 @Excel 配置直接导出表

实体类:

package web_test.model;

import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.util.Date;

/**
 * @author shenlongdaxia
 */
@EqualsAndHashCode(callSuper = false)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ExportEntity {

    @Excel(name = "序号", needMerge = true)
    private Integer serialNum;

    @Excel(name = "姓名", needMerge = true)
    private String name;

    @Excel(name = "性别", needMerge = true, replace = {"男_true", "女_false"}, width = 15.0)
    private Boolean sex;

    @Excel(name = "电话", needMerge = true)
    private String phone;

    @Excel(name = "购买时间", format = "yyyy-MM-dd HH:mm:ss", needMerge = true, width = 20.0)
    private Date buyTime;

    @Excel(name = "住址", needMerge = true, width = 15.0)
    private String address;

    @Excel(name = "水果", groupName = "订单类别", width = 15.0)
    private String fruitsName;

    @Excel(name = "蔬菜", groupName = "订单类别", width = 15.0)
    private String vegetableName;

}

controller:

@GetMapping(value = "/exportExcelTest")
    public void exportExcelTest(HttpServletResponse response) {
        apiTestService.exportExcelTest(response);
    }

serviceImpl:

 @Override
    public void exportExcelTest(HttpServletResponse response) {

        // ================= 准备环节 ==================

        LinkedList<ExportEntity> entities = new LinkedList<>();
        // 先造一些数据
        for (int i = 1; i < 101; i++) {
            ExportEntity entity = new ExportEntity(i, "zs" + i, i % 2 == 0, "134" + i, new Date(),
                    "模板之汤臣" + i + "品", i + "个苹果", i + "个西红柿");
            entities.add(entity);
        }

        //  ================= 主要环节 ==================


        IWriter<Workbook> writer = ExcelExportUtil.exportBigExcel(new ExportParams(null, "测试"), ExportEntity.class);
        writer.write(entities);
        Workbook workbook = writer.get();

        // 获取工作簿

        // ================= 结束输出 ==================
        // 输出
        responseWorkbook(response, workbook, "大数据导出.xlsx");
    }

    /**
     * 导出 Excel
     *
     * @param response
     * @param workbook
     * @param fileName
     */
    private static void responseWorkbook(HttpServletResponse response, Workbook workbook, String fileName) {

        try {
            response.setHeader("Content-disposition", "attachment;" + "filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/octet-stream; charset=UTF-8");
            workbook.write(response.getOutputStream());

            workbook.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

结果:

完美~😎


方法二:在导入的方法中查数据

关键代码:ExcelExportUtil.exportBigExcel(ExportParams entity, Class<?> pojoClass,
IExcelExportServer server, Object queryParams);

entity:导出参数,还是基本导出的那两个,直接开 new

pojoClass:导出文件内容的类的字节码类型

server: 在这个 server 里面通过自身的业务层的分页逻辑去数据库获取大数据内容,比如通过mybatisPlus 的分页逻辑来获取内容数据

queryParams:server 分页查询内容的过滤条件

这种的导出效果和 方法一的导出效果是一样的,它利用的是 分页查询 来查的数据,大爷们可以看看下方链接,也挺好实现的💕(内心os:码不动了)

Easypoi-大数据量导出_easypoi 大数据导出-CSDN博客

【springboot+easypoi】大数据量excel导出 - 简书 (jianshu.com)

  • 14
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
好的,这里给你一个完整的例子,演示如何使用easypoi导出excel模板。假设你有一个excel模板文件`template.xlsx`,其中有一张名为`Sheet1`的表格,需要填充数据后导出为`output.xlsx`文件。 ```java import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.entity.TemplateExportParams; import org.apache.poi.ss.usermodel.Workbook; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class ExcelTemplateExporter { public static void main(String[] args) throws IOException { // 创建填充数据的Map Map<String, Object> data = new HashMap<>(); data.put("name", "张三"); data.put("age", 18); data.put("gender", "男"); // 创建excel导出参数 TemplateExportParams params = new TemplateExportParams("template.xlsx"); // 导出excel文件 Workbook workbook = ExcelExportUtil.exportExcel(params, data); FileOutputStream fos = new FileOutputStream("output.xlsx"); workbook.write(fos); fos.close(); System.out.println("Excel导出成功!"); } } ``` 这个例子中,我们首先创建了一个`Map`对象,将需要填充的数据放入其中。接着,我们创建了一个`TemplateExportParams`对象,指定了excel模板文件的路径。最后,我们调用`ExcelExportUtil.exportExcel`方法,将模板和填充数据传入,得到一个填充好数据的`Workbook`对象。最后将`Workbook`对象输出为`output.xlsx`文件。 需要注意的是,这个例子中使用的是easypoi库,相较于poi库,easypoi库可以更快速、简便地进行excel导入导出,并且支持更多的excel操作功能。在实际项目中,你可以根据具体需求选择使用不同的excel库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神龙大侠学java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值