java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > EasyExcel读写、模板填充、Web上传下载

EasyExcel读写、模板填充、Web上传下载入门到实战全指南

作者:五阿哥永琪

EasyExcel类是一套基于Java的开源Excel解析工具类,相较于传统的框架如Apache poi、jxl等更加快速、简洁,还可以解决大文件内存溢出问题,这篇文章主要介绍了EasyExcel读写、模板填充、Web上传下载入门到实战的相关资料,需要的朋友可以参考下

EasyExcel 是阿里巴巴开源的一款 基于 Java 的高性能、简单易用的 Excel 读写工具库,专注于解决使用 Apache POI(Java 操作 Excel 的底层库)时常见的 内存溢出(OOM)API 复杂 问题。

一、 主要功能

1. 读 Excel(支持 .xls / .xlsx)

EasyExcel.read(fileName, DemoData.class, new MyReadListener())
         .sheet()
         .doRead();

2. 写 Excel

EasyExcel.write(fileName, DemoData.class)
         .sheet("Sheet1")
         .doWrite(dataList);

3. Excel 填充(模板填充)

EasyExcel.write(out, DemoData.class)
         .withTemplate(templateFile)
         .sheet()
         .doFill(data);

4. 丰富的注解支持

public class User {
    @ExcelProperty("用户姓名")
    private String name;

    @ExcelProperty("注册时间")
    @DateTimeFormat("yyyy年MM月dd日")
    private Date registerTime;
}

二、 快速开始

1. 引入依赖

<!--Lombok依赖-->  
<dependency>  
    <groupId>org.projectlombok</groupId>  
    <artifactId>lombok</artifactId>  
    <optional>true</optional>  
</dependency>  
<!--easyexcel依赖-->  
<dependency>  
    <groupId>com.alibaba</groupId>  
    <artifactId>easyexcel</artifactId>  
    <version>4.0.3</version>  
</dependency>  
<!--fastjson依赖-->  
<dependency>  
    <groupId>com.alibaba</groupId>  
    <artifactId>fastjson</artifactId>  
    <version>2.0.57</version>  
</dependency>

2. 写实体类

package com.nuc.demoexcel.entity;  
  
import com.alibaba.excel.annotation.ExcelIgnore;  
import com.alibaba.excel.annotation.ExcelProperty;  
import com.alibaba.excel.annotation.write.style.ColumnWidth;  
import com.alibaba.excel.annotation.write.style.HeadRowHeight;  
import com.alibaba.fastjson.annotation.JSONField;  
import lombok.Data;  
  
import java.util.Date;  
  
@Data  
@HeadRowHeight(20)  
@ColumnWidth(20)  
public class DemoDate {  
    @ExcelProperty("字符串标题")  
    private String name;  
    @ExcelProperty("日期标题")  
    @JSONField(format = "yyyy-MM-dd,HH:mm:ss") // 格式化日期 没有注解会默认转成时间戳  
    private Date date;  
    @ExcelProperty("数字标题")  
    private Double doubleData;  
    @ExcelIgnore  
    private String ignore;  
}

3. Excel读取

读取常用有三种方法

方法一:

有封装的实体类
.head(DemoData.class)封装
结果用List<DemoData>

/**  
 * 测试读1  
 * 有封装的实体类  
 */  
@Test  
void readExcel1() {  
    System.out.println("测试");  
    List<DemoDate> list = EasyExcel.read("D:\\测试\\demo.xlsx").head(DemoDate.class).sheet().doReadSync();  
    list.forEach(data ->{  
        String jsonString = JSON.toJSONString(data);  
        log.info("读取到数据{}",jsonString);  
    });  
}

方法二:没有封装的实体类

没有封装的实体类
结果用List<Map<Integer,String>>

/**  
 * 测试读2  
 * 没有分装的实体类用Map来存  
 */  
@Test  
void readExcel2() {  
    System.out.println("测试");  
    List<Map<Integer,String>> list = EasyExcel.read("D:\\测试\\demo.xlsx").sheet().doReadSync();  
    list.forEach(data ->{  
        String string = data.toString();  
        log.info("读取到数据{}",string);  
    });  
}

方法三:使用监听器来读取文件

使用监听器来读取文件

/**  
 * 测试读3  
 * 使用监听器读取文件。  
 * 需要我们额外创建一个监听器  
 */  
@Test  
void readExcel3() {  
    System.out.println("测试");  
    EasyExcel.read("D:\\测试\\demo.xlsx", DemoDate.class, new ExcelListener(demoService)).sheet().doRead();  
}
package com.nuc.demoexcel.listener;  
  
import com.alibaba.excel.context.AnalysisContext;  
import com.alibaba.excel.event.AnalysisEventListener;  
import com.alibaba.fastjson.JSON;  
import com.nuc.demoexcel.entity.DemoDate;  
import com.nuc.demoexcel.service.DemoService;  
import lombok.RequiredArgsConstructor;  
import lombok.extern.slf4j.Slf4j;  
  
import java.util.ArrayList;  
import java.util.List;  
  
/**  
 * 这里不能用SprongIoC容器来管理Listener,Listener可添加多个,会自动执行  
 */  
@Slf4j  
@RequiredArgsConstructor  
public class ExcelListener extends AnalysisEventListener<DemoDate> {  
  
    /**  
     * 每隔5条存储数据库,清理list,方便内存回收  
     */  
    private static final int BATCH_COUNT = 5;  
    private List<DemoDate> list = new ArrayList<DemoDate>();  
    private final DemoService demoService;  
  
    @Override  
    public void invoke(DemoDate demoDate, AnalysisContext analysisContext) {  
        log.info("读取到数据{}", JSON.toJSONString(demoDate));  
        list.add(demoDate);  
        // 到达批次数,保存数据,防止数据几万条数据在内存中,容易OOM  
        if (list.size() >= BATCH_COUNT) {  
            saveData();  
            // 保存完成,清理list  
            list.clear();  
        }  
  
    }  
  
  
    /**  
     * 所有的数据都读完,最后收尾数据  
     * @param analysisContext  
     */  
    @Override  
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {  
        //这里也要保存数据,确保最后遗留的数据也存储到数据库  
        saveData();  
        log.info("所有数据解析完成!");  
    }  
  
    /**  
     * 存储数据到数据库  
     */  
    private void saveData() {  
        log.info("{}条数据,开始存储数据库!", list.size());  
        demoService.saveData(list);  
        log.info("存储数据库成功!");  
    }  
}

这里只是演示EasyExcel
所以就不写Service层代码

4. Excel写入

  
/**  
 * 测试写  
 */  
@Test  
void testWrite() {  
    // 文件输出位置  
    String fileName = "D:\\text" + System.currentTimeMillis() + ".xlsx";  
    EasyExcel.write(fileName, DemoDate.class).sheet("模板").doWrite(data());  
  
  
  
}  
  
private List<DemoDate> data(){  
    //模拟数据  
    List<DemoDate> list = new ArrayList<>();  
    for (int i = 0; i < 13; i++) {  
        DemoDate data = new DemoDate();  
        data.setName("张三"+i);  
        data.setDate(new Date());  
        data.setDoubleData(Math.random()*100);  
        list.add(data);  
    }  
    return list;  
}

5. Excel下载&上传

package com.nuc.demoexcel.controller;  
  
import com.alibaba.excel.EasyExcel;  
import com.alibaba.fastjson.JSON;  
import com.nuc.demoexcel.entity.DemoDate;  
import com.nuc.demoexcel.listener.ExcelListener;  
import com.nuc.demoexcel.service.DemoService;  
import jakarta.servlet.http.HttpServletResponse;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.PostMapping;  
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.bind.annotation.ResponseBody;  
import org.springframework.web.multipart.MultipartFile;  
  
import java.io.IOException;  
import java.net.URLEncoder;  
import java.util.*;  
  
@Controller  
public class UploadDownController {  
  
    @Autowired  
    private DemoService demoService;  
  
    /**  
     * 下载失败了(会返回一个有部分数据的Excel)  
     * @param response  
     * @throws IOException  
     */    @RequestMapping("/download")  
    public void download(HttpServletResponse  response) throws IOException {  
        response.setContentType("application/vnd.ms-excel");  
        response.setCharacterEncoding("utf-8");  
        //这里的encode是解决中文乱码, 这里必须使用UTF-8, 不然乱码  
        String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");  
        //这里使用附件的形式下载  
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");  
        EasyExcel.write(response.getOutputStream(), DemoDate.class).sheet("模板").doWrite(data());  
    }  
  
  
    @RequestMapping("/api/download")  
    public void downloadApi(HttpServletResponse response) throws IOException {  
        try {  
            response.setContentType("application/vnd.ms-excel");  
            response.setCharacterEncoding("utf-8");  
            //这里的encode是解决中文乱码, 这里必须使用UTF-8, 不然乱码  
            String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");  
            //这里使用附件的形式下载  
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");  
            EasyExcel.write(response.getOutputStream(), DemoDate.class).sheet("模板").doWrite(data());  
        } catch (IOException e) {  
            //重置响应  
            response.reset();  
            response.setContentType("application/json");  
            response.setCharacterEncoding("utf-8");  
            Map<String, Object> map = new HashMap<>();  
            map.put("status", 500);  
            map.put("message", "数据写入失败" + e.getMessage());  
            response.getWriter().println(JSON.toJSONString(map));  
        }  
  
    }  
  
    @PostMapping("/upload")  
    @ResponseBody  
    public String upload(MultipartFile file) throws IOException {  
        EasyExcel.read(file.getInputStream(), DemoDate.class, new ExcelListener(demoService)).sheet().doRead();  
        return "success";  
    }  
  
    private List<DemoDate> data(){  
        //模拟数据  
        List<DemoDate> list = new ArrayList<>();  
        for (int i = 0; i < 13; i++) {  
            DemoDate data = new DemoDate();  
            data.setName("张三"+i);  
            data.setDate(new Date());  
            data.setDoubleData(Math.random()*100);  
            list.add(data);  
        }  
        return list;  
    }  
}

5. Excel下载&上传

package com.nuc.demoexcel.controller;  
  
import com.alibaba.excel.EasyExcel;  
import com.alibaba.fastjson.JSON;  
import com.nuc.demoexcel.entity.DemoDate;  
import com.nuc.demoexcel.listener.ExcelListener;  
import com.nuc.demoexcel.service.DemoService;  
import jakarta.servlet.http.HttpServletResponse;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.PostMapping;  
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.bind.annotation.ResponseBody;  
import org.springframework.web.multipart.MultipartFile;  
  
import java.io.IOException;  
import java.net.URLEncoder;  
import java.util.*;  
  
@Controller  
public class UploadDownController {  
  
    @Autowired  
    private DemoService demoService;  
  
    /**  
     * 下载失败了(会返回一个有部分数据的Excel)  
     * @param response  
     * @throws IOException  
     */    @RequestMapping("/download")  
    public void download(HttpServletResponse  response) throws IOException {  
        response.setContentType("application/vnd.ms-excel");  
        response.setCharacterEncoding("utf-8");  
        //这里的encode是解决中文乱码, 这里必须使用UTF-8, 不然乱码  
        String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");  
        //这里使用附件的形式下载  
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");  
        EasyExcel.write(response.getOutputStream(), DemoDate.class).sheet("模板").doWrite(data());  
    }  
  
  
    @RequestMapping("/api/download")  
    public void downloadApi(HttpServletResponse response) throws IOException {  
        try {  
            response.setContentType("application/vnd.ms-excel");  
            response.setCharacterEncoding("utf-8");  
            //这里的encode是解决中文乱码, 这里必须使用UTF-8, 不然乱码  
            String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");  
            //这里使用附件的形式下载  
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");  
            EasyExcel.write(response.getOutputStream(), DemoDate.class).sheet("模板").doWrite(data());  
        } catch (IOException e) {  
            //重置响应  
            response.reset();  
            response.setContentType("application/json");  
            response.setCharacterEncoding("utf-8");  
            Map<String, Object> map = new HashMap<>();  
            map.put("status", 500);  
            map.put("message", "数据写入失败" + e.getMessage());  
            response.getWriter().println(JSON.toJSONString(map));  
        }  
  
    }  
  
    @PostMapping("/upload")  
    @ResponseBody  
    public String upload(MultipartFile file) throws IOException {  
        EasyExcel.read(file.getInputStream(), DemoDate.class, new ExcelListener(demoService)).sheet().doRead();  
        return "success";  
    }  
  
    private List<DemoDate> data(){  
        //模拟数据  
        List<DemoDate> list = new ArrayList<>();  
        for (int i = 0; i < 13; i++) {  
            DemoDate data = new DemoDate();  
            data.setName("张三"+i);  
            data.setDate(new Date());  
            data.setDoubleData(Math.random()*100);  
            list.add(data);  
        }  
        return list;  
    }  
}

总结 

到此这篇关于EasyExcel读写、模板填充、Web上传下载入门到实战的文章就介绍到这了,更多相关EasyExcel读写、模板填充、Web上传下载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文