EasyExcel工具类实现导入导出

**

java利用EasyExcel简单快捷实现文件的导入导出功能

**

EasyExcel特点

生成Excel比较有名的框架有Apache poi,jxl等,但都存在一个严重的问题就是非常的耗内存,系统并发量不大的话可能还行,否则并发上来后一定会OOM或者JVM频繁的full gc.

EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单,节省内存著称,EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)。

所需依赖

        <!-- 阿里巴巴Excel处理-->
        <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.1.6</version>
        </dependency>

        <!-- 工具类-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.4.0</version>
        </dependency>

hutool工具类十分强大,可自行到官网查看文档。https://www.hutool.cn/docs/#/**

导入导出实体类

public class TyGoodsCategory implements Serializable {
    private static final long serialVersionUID = -41708876706950978L;

    @ExcelProperty(value = "ID",index = 0)
    private Integer id;
    /**
     * 类型 1:产品分类 2:渠道分类 3:食材库分类 4:成品库分类
     */
    @ExcelProperty(value = "类型",index = 1)
    private Byte type;

    /**
     * 商品分类名称
     */
    @ExcelProperty(value = "商品分类名称",index = 2)
    private String name;

    /**
     * 父级id
     */
    @ExcelProperty(value = "父级id",index = 3)
    private Integer pId;
    /**
     * 家族图谱
     */
    @ExcelProperty(value = "家族图谱",index = 4)
    private String path;
    /**
     * 等级
     */
    @ExcelProperty(value = "等级",index = 5)
    private Byte level;
    /**
     * 顺序排序
     */
    @ExcelProperty(value = "顺序排序",index = 6)
    private Integer sort;
    /**
     * 1显示  0不显示
     */
    @ExcelProperty(value = "是否显示",index = 7)
    private Boolean isShow;
    /**
     * 1热门 0不否
     */
    @ExcelProperty(value = "是否热门",index = 8)
    private boolean isHot;

/*    @TableField(fill = FieldFill.INSERT_UPDATE)//创建与修改时自动填充
    private Date updateTime;*/

    @ExcelProperty(value = "创建时间",index = 9)
    @TableField(fill = FieldFill.INSERT) //创建时自动填充
    //@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    @ExcelProperty(value = "更新时间",index = 10)
    @TableField(fill = FieldFill.UPDATE)
    private Date updateTime;

    /**
     * 子类集合
     */
    // 不需要导出的字段
    @ExcelIgnore
    // 不属于数据库字段
    @TableField(exist = false)
    private List<TyGoodsCategory> childrenList;
    }

备注:不需要导出的字段可用注解@ExcelIgnore标识

excel导入监听类

public class ExcelListener extends AnalysisEventListener {
    /**
     * 可以通过实例获取该值
     */
    private List<Object> dataList = new ArrayList<>();

    @Override
    public void invoke(Object object, AnalysisContext context) {
        //数据存储到list,供批量处理,或后续自己业务逻辑处理。
        dataList.add(object);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        //非必要语句,查看导入的数据
        System.out.println("导入的数据条数为: " + dataList.size());
    }

    public List<Object> getDataList() {
        return dataList;
    }

    public void setDataList(List<Object> dataList) {
        this.dataList = dataList;
    }
}

导入导出工具类

备注:该工具类可直接传入结果集调用fileExport()方法进行excel文件导出。导入调用readExcel()方法可以直接转换为list集合

package com.ruoyi.common.core.utils;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.ruoyi.common.core.constant.HttpStatus;
import org.apache.poi.ss.usermodel.HorizontalAlignment;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;



/**
 * 导入导出工具类
 */
public class ExcelSelfUtil {

    /**
     *  通用导出
     * @param list 数据集合
     * @param response
     * @param clazz 对象类型  *.class
     */
    public static void fileExport(List<?> list, HttpServletResponse response, Class<?> clazz) throws IOException {
        ServletOutputStream out = response.getOutputStream();
        response.setContentType("multipart/form-data");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Disposition", "attachment;filename*=utf-8'zh_cn'" + URLEncoder.encode(System.currentTimeMillis() + ".csv", "UTF-8"));
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //设置表头居中对齐
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //内容样式
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //设置内容靠左对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        EasyExcel.write(out, clazz).autoCloseStream(true).registerWriteHandler(horizontalCellStyleStrategy).sheet("信息列表").doWrite(list);
        out.flush();
    }

    public static void fileExportForName(List<?> list, String fileName, HttpServletResponse response, Class<?> clazz) throws IOException {
        ServletOutputStream out = response.getOutputStream();
        response.setContentType("multipart/form-data");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Disposition", "attachment;filename*=utf-8'zh_cn'" + URLEncoder.encode(fileName + ".csv", "UTF-8"));
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //设置表头居中对齐
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //内容样式
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //设置内容靠左对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        EasyExcel.write(out, clazz).autoCloseStream(true).registerWriteHandler(horizontalCellStyleStrategy).sheet("信息列表").doWrite(list);
        out.flush();
    }

    /**
     * 读取Excel(多个sheet可以用同一个实体类解析)
     * @param excelInputStream
     * @param fileName
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> readExcel(InputStream excelInputStream, String fileName, Class<T> clazz) {
        ExcelListener excelListener = new ExcelListener();
        ExcelReader excelReader = getReader(excelInputStream, fileName,clazz, excelListener);
        if (excelReader == null) {
            return new ArrayList<>();
        }
        List<ReadSheet> readSheetList = excelReader.excelExecutor().sheetList();
        for (ReadSheet readSheet : readSheetList) {
            excelReader.read(readSheet);
        }
        excelReader.finish();
        return Convert.toList(clazz, excelListener.getDataList());
    }



    /**
     * 导出
     *
     * @param response
     * @param data
     * @param fileName
     * @param sheetName
     * @param clazz
     * @throws Exception
     */
    public static void writeExcel(HttpServletResponse response, List<?> data, String fileName, String sheetName, Class clazz) throws Exception {
        OutputStream outputStream = getOutputStream(fileName, response);
        EasyExcel.write(outputStream, clazz).autoCloseStream(true).sheet(sheetName).doWrite(data);
        outputStream.flush();
    }

    /**
     * 流方式响应给前端
     * @param fileName
     * @param response
     * @return
     * @throws Exception
     */
    private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception {
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".csv");
        response.setStatus(HttpStatus.SUCCESS);
        return response.getOutputStream();
    }

    /**
     * 返回ExcelReader
     *
     * @param clazz 实体类
     * @param excelListener
     */
    private static <T> ExcelReader getReader(InputStream inputStream, String filename, Class<T> clazz, ExcelListener excelListener) {
        try {
            if (filename == null ||
                    (!filename.toLowerCase().endsWith(".xls") && !filename.toLowerCase().endsWith(".csv"))) {
                return null;
            }
            ExcelReader excelReader = EasyExcel.read(inputStream, clazz, excelListener).build();
            inputStream.close();
            return excelReader;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

测试 Controller

    /**
     * 导出测试
     * @param tyGoodsCategory
     * @param response
     */
    @PostMapping("test1")
    public void test1(@RequestBody TyGoodsCategory tyGoodsCategory, HttpServletResponse response){
        MyAssert.MyAssert4Operation.notNull(tyGoodsCategory);
        MyAssert.MyAssert4Operation.notNull(tyGoodsCategory.getType(), "未指定查询的分类类型!");
        tyGoodsCategoryService.test1(tyGoodsCategory, response);
    }

    /**
     * 导入测试
     * @param excel
     * @return  返回值为导入的数据集合
     * @throws IOException
     */
    @PostMapping(value = "/import")
    public List<TyGoodsCategory> read(@RequestParam("files") MultipartFile excel) throws IOException {
        return ExcelUtil.readExcel(excel.getInputStream(), excel.getOriginalFilename(), TyGoodsCategory.class);
    }

测试 service

    @Override
    public void test1(TyGoodsCategory tyGoodsCategory, HttpServletResponse response) {
        QueryWrapper<TyGoodsCategory> wrapper = new QueryWrapper<>();
        wrapper.eq("type", tyGoodsCategory.getType());
        Page<TyGoodsCategory> page = new Page<>(tyGoodsCategory.getPageNum(), tyGoodsCategory.getPageSize());
        // 自定义sql查询 可用于多表
        Page<TyGoodsCategory> tyGoodsCategoryPage = tyGoodsCategoryDao.selectMyPage(page, tyGoodsCategory);
        List<TyGoodsCategory> records = tyGoodsCategoryPage.getRecords();
        ExcelUtil.fileExport(records, response, TyGoodsCategory.class);
    }

调用导出接口![Alt]在这里插入图片描述

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
EasyExcel 是一个基于 Java 的简单、高效、无侵入的 Excel 文件读写工具包,可以快速方便地实现 Excel 文件的读写操作。下面是一个 easyexcel 工具类的示例: ```java public class ExcelUtil { /** * 读取 Excel 文件内容 * * @param inputStream Excel 文件输入流 * @param clazz 数据模型 * @return 读取结果 */ public static <T> List<T> readExcel(InputStream inputStream, Class<T> clazz) { List<T> dataList = new ArrayList<>(); try { // 创建读取 Excel 文件的工作簿对象 ExcelReader excelReader = new ExcelReader(inputStream, null, new AnalysisEventListener<T>() { @Override public void invoke(T data, AnalysisContext context) { // 读取到一行数据时的回调方法 dataList.add(data); } @Override public void doAfterAllAnalysed(AnalysisContext context) { // 读取结束时的回调方法 } }); // 读取 Excel 文件中的数据并转换为指定的数据模型 excelReader.read(new Sheet(1, 1, clazz)); } catch (Exception e) { e.printStackTrace(); } return dataList; } /** * 写入数据到 Excel 文件 * * @param outputStream Excel 文件输出流 * @param dataList 数据列表 * @param clazz 数据模型 */ public static <T> void writeExcel(OutputStream outputStream, List<T> dataList, Class<T> clazz) { try { // 创建写入 Excel 文件的工作簿对象 ExcelWriter excelWriter = new ExcelWriter(outputStream, ExcelTypeEnum.XLSX); // 创建写入 Excel 文件的 sheet 对象 Sheet sheet = new Sheet(1, 0, clazz); // 写入数据到 Excel 文件 excelWriter.write(dataList, sheet); // 关闭写入 Excel 文件的工作簿对象 excelWriter.finish(); } catch (Exception e) { e.printStackTrace(); } } } ``` 使用示例: ```java // 读取 Excel 文件 List<User> userList = ExcelUtil.readExcel(new FileInputStream("user.xlsx"), User.class); // 写入数据到 Excel 文件 List<User> userList = new ArrayList<>(); userList.add(new User("张三", 30, "男")); userList.add(new User("李四", 25, "女")); ExcelUtil.writeExcel(new FileOutputStream("user.xlsx"), userList, User.class); ``` 其中 `User` 为数据模型,示例代码如下: ```java public class User { private String name; private Integer age; private String gender; public User() { } public User(String name, Integer age, String gender) { this.name = name; this.age = age; this.gender = gender; } // getter 和 setter 方法省略 } ``` 以上代码仅为示例,具体的应用场景中可能需要根据实际需求进行适当的修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值