IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot 使用 EasyExcel 实现Excel文件的导入导出 -> 正文阅读

[Java知识库]SpringBoot 使用 EasyExcel 实现Excel文件的导入导出

1. EasyExcel介绍

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

2. EasyExcel特点

  • Java 领域解析、生成 Excel 比较有名的框架有 Apache poi、jxl 等。但他们都存在一个严重的问题就是非常的耗内存。如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM(Out Of Memory) 或者 JVM 频繁的 full gc(垃圾回收)。
  • EasyExcel 采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)
  • EasyExcel 是一个基于Java的简单、省内存的读写 Excel 的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。
  • EasyExcel 与 Apache poi 对比

EasyExcel

Apache poi

一行一行进行解析

一次性把所有数据加载到内存中,进行解析

查询方便

添加、修改、删除方便

3. Excel术语介绍

  • 整个 excel 称为 workbook
  • 每个 workbook 里面有很多 sheet
  • 在每个 sheet 里面有行、列、单元格

4. EasyExcel写操作

(1)pom中引入xml相关依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>2.1.1</version>
    </dependency>
</dependencies>

(2)创建实体类,和excel对应

设置表头和添加的数据字段

@Data
public class Student {
    //设置表头名称
    @ExcelProperty("学生编号")
    private int sno;
    //设置表头名称
    @ExcelProperty("学生姓名")
    private String sname;
}

(3)实现写操作

创建方法循环设置要添加到Excel的数据:

//循环设置要添加的数据,最终封装到list集合中
private static List<Student> data() {
    List<Student> list = new ArrayList<Student>();
    for (int i = 0; i < 10; i++) {
        Student student = new Student();
        student.setSno(i);
        student.setSname("张三"+i);
        list.add(student);
    }
    return list;
}

(4)实现最终的添加操作:

public static void main(String[] args) throws Exception {
    // 写法1
    String fileName = "D:\test01.xlsx";
    // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
    // 如果这里想使用03 则 传入excelType参数即可
    EasyExcel.write(fileName, Student.class).sheet("写入方法").doWrite(data());
}

(5)结果:

5. EasyExcel读操作

(1)创建实体类,和excel对应

@Data
public class Student {
    //设置表头名称
    //设置列对应的属性
	// index = 0 表示第一列
	// index = 1 表示第二列
    @ExcelProperty(value = "学生编号",index = 0)
    private int sno;
    
    @ExcelProperty(value = "学生姓名",index = 1)
    private String sname;
}

(2)创建读取操作的监听器

public class ExcelListener extends AnalysisEventListener<Student> {
    //创建list集合封装最终的数据
    List<Student> list = new ArrayList<Student>();
    //一行一行去读取excle内容
    @Override
    public void invoke(Student student, AnalysisContext analysisContext) {
        System.out.println("***"+student);
        list.add(student);
    }
    //读取excel表头信息
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        System.out.println("表头信息:"+headMap);
    }
    //读取完成后执行
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    }
}

(3)调用实现最终的读取

 public static void main(String[] args) throws Exception {
        String fileName = "D:\test01.xlsx";
        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
        EasyExcel.read(fileName, Student.class, new ExcelListener()).sheet().doRead();
}

(4)结果:

6. Excel文件导入导出逻辑

(1)导出逻辑

public void exportData(HttpServletResponse response) {
        try {
            // 设置下载信息
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然这和easyexcel没有关系
            String fileName = URLEncoder.encode("课程分类", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");

            // 查询课程分类表所有数据
            List<Subject> dictList = baseMapper.selectList(null);

            // 将Subject-->SubjectEeVo
            List<SubjectEeVo> dictVoList = new ArrayList<>(dictList.size());
            for(Subject dict : dictList) {
                SubjectEeVo dictVo = new SubjectEeVo();
                BeanUtils.copyProperties(dict,dictVo);
                dictVoList.add(dictVo);
            }
            // 用EasyExcel写操作
            EasyExcel.write(response.getOutputStream(), SubjectEeVo.class).sheet("课程分类").doWrite(dictVoList);
        } catch (IOException e) {
            e.printStackTrace();
            throw new GgktException(20001, "导出失败");
        }
    }

以上用到的两个实体信息:

@Data
@ApiModel(description = "Subject")
@TableName("subject")
public class Subject {

	private static final long serialVersionUID = 1L;
	@ApiModelProperty(value = "id")
	private Long id;

	@ApiModelProperty(value = "创建时间")
	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
	@TableField("create_time")
	private Date createTime;

	@ApiModelProperty(value = "更新时间")
	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
	@TableField("update_time")
	private Date updateTime;

	@ApiModelProperty(value = "逻辑删除(1:已删除,0:未删除)")
	@JsonIgnore
	@TableLogic
	@TableField("is_deleted")
	private Integer isDeleted;

	@ApiModelProperty(value = "其他参数")
	@TableField(exist = false)
	private Map<String,Object> param = new HashMap<>();

	@ApiModelProperty(value = "类别名称")
	@TableField("title")
	private String title;

	@ApiModelProperty(value = "父ID")
	@TableField("parent_id")
	private Long parentId;

	@ApiModelProperty(value = "排序字段")
	@TableField("sort")
	private Integer sort;

	@ApiModelProperty(value = "是否包含子节点")
	@TableField(exist = false) // 表示表里面没有这个字段,但是这个属性要用到
	private boolean hasChildren;

}
@Data
public class SubjectEeVo {

	@ExcelProperty(value = "id" ,index = 0)
	private Long id;

	@ExcelProperty(value = "课程分类名称" ,index = 1)
	private String title;

	@ExcelProperty(value = "上级id" ,index = 2)
	private Long parentId;

	@ExcelProperty(value = "排序" ,index = 3)
	private Integer sort;


}

(2)导入逻辑:

? 创建读取监听器:

@Component
public class SubjectListener extends AnalysisEventListener<SubjectEeVo> {
    @Autowired
    private SubjectMapper subjectMapper;
    //一行一行读取
    @Override
    public void invoke(SubjectEeVo subjectEeVo, AnalysisContext analysisContext) {
        //调用方法添加数据库
        Subject subject = new Subject();
        BeanUtils.copyProperties(subjectEeVo,subject);
        subjectMapper.insert(subject);
    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    }
}
@Autowired
private SubjectListener subjectListener;

//导入
@Override
public void importData(MultipartFile file) {
    try {
        EasyExcel.read(file.getInputStream(),
                       SubjectEeVo.class,subjectListener).sheet().doRead();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 18:50:24  更:2022-08-19 18:51:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:16:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码