小工具知识网

当前位置: 首页 > 行业知识 > springboot使用EasyExcel实现Excel导入导出

行业知识

springboot使用EasyExcel实现Excel导入导出

2026-11-13 04:09:52 来源:互联网转载

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

()

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

1、pom添加easyexcel依赖

com.alibabaeasyexcel3.1.3 org.projectlomboklomboktruecn.hutoolhutool-all5.8.18

2、实体类UserDO与Excel数据对应

@Datapublic class UserDO {    // 设置excel表头名称    @ExcelProperty("用户编号")    @ColumnWidth(20)    private Long id;        // 设置该列的名称为'用户名';    @ExcelProperty("用户名")    // 设置表格列的宽度为20    @ColumnWidth(20)    private String username;    // 导出时忽略该字段    @ExcelIgnore    private String password;    @ExcelProperty("昵称")    @ColumnWidth(20)    private String nickname;    @ExcelProperty("生日")    @ColumnWidth(20)    // 按照指定的格式对日期进行格式化;    @DateTimeFormat("yyyy-MM-dd")    private Date birthday;    @ExcelProperty("手机号")    @ColumnWidth(20)    private String phone;    @ExcelProperty("身高(米)")    @NumberFormat("#.##")    @ColumnWidth(20)    private Double height;    // 自定义内容转换器    @ExcelProperty(value = "性别", converter = GenderConverter.class)    @ColumnWidth(10)    private Integer gender;}

常用注解有:

()

@ExcelProperty 指定当前字段对应excel中的哪一列。可以根据名字或者Index去匹配。当然也可以不写,默认第一个字段就是index=0,以此类推。千万注意,要么全部不写,要么全部用index,要么全部用名字去匹配。千万别三个混着用,除非你非常了解源代码中三个混着用怎么去排序的。

@ExcelIgnore EasyExcel默认所有字段都会和excel去匹配,加了这个注解会忽略该字段

@DateTimeFormat 日期转换,用String去接收excel日期格式的数据会调用这个注解。里面的value参照java.text.SimpleDateFormat

@NumberFormat 数字转换,用String去接收excel数字格式的数据会调用这个注解。里面的value参照java.text.DecimalFormat

3、converter自定义转换器

自定义转换器将数据库中表示性别的1、0转换成男、女

  3.1、GenderConverter 

/** * 性别转换器 * */public class GenderConverter implements Converter {    @Override    public Class supportJavaTypeKey() {        // 实体类中对象属性类型        return Integer.class;    }    @Override    public CellDataTypeEnum supportExcelTypeKey() {        // Excel中对应的CellData(单元格数据)属性类型        return CellDataTypeEnum.STRING;    }    /**     * 将单元格里的数据转为java对象,也就是女转成2,男转成1,用于导入excel时对性别字段进行转换     * */    @Override    public Integer convertToJavaData(ReadConverterContext context) throws Exception {        // 从CellData中读取数据,判断Excel中的值,将其转换为预期的数值        return GenderEnum.convert(context.getReadCellData().getStringValue()).getValue();    }    /**     * 将java对象转为单元格数据,也就是2转成女,1转成男,用于导出excel时对性别字段进行转换     * */    @Override    public WriteCellData convertToExcelData(WriteConverterContext context) throws Exception {        // 判断实体类中获取的值,转换为Excel预期的值,并封装为CellData对象        return new WriteCellData(GenderEnum.convert(context.getValue()).getDescription());    }}

 3.2、GenderEnum

@Getter@AllArgsConstructorpublic enum GenderEnum {    /**     * 未知     */    UNKNOWN(0, "未知"),    /**     * 男性     */    MALE(1, "男性"),    /**     * 女性     */    FEMALE(2, "女性");    private final Integer value;    @JsonFormat    private final String description;    public static GenderEnum convert(Integer value) {//        用于为给定元素创建顺序流//        values:获取枚举类型的对象数组        return Stream.of(values())                .filter(bean -> bean.value.equals(value))                .findAny()                .orElse(UNKNOWN);    }    public static GenderEnum convert(String description) {        return Stream.of(values())                .filter(bean -> bean.description.equals(description))                .findAny()                .orElse(UNKNOWN);    }}

4、导出

/** * 设置响应结果 * * @param response    响应结果对象 * @param rawFileName 文件名 * @throws UnsupportedEncodingException 不支持编码异常 */private void setExcelResponseProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException {//设置内容类型response.setContentType("application/vnd.vnd.ms-excel");//设置编码格式response.setCharacterEncoding("utf-8");//设置导出文件名称(避免乱码)String fileName = URLEncoder.encode(rawFileName.concat(".xlsx"), "UTF-8");// 设置响应头response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);}private Date getBirthday(int year, int month, int day){Calendar calendar = Calendar.getInstance();calendar.set(year, month, day);return calendar.getTime();}/** * 导出数据 * */@GetMapping("/export/user")public void exportUserExcel(HttpServletResponse response) throws IOException {OutputStream outputStream = response.getOutputStream();try {this.setExcelResponseProp(response, "用户列表");// 模拟根据条件在数据库查询数据List userList = new ArrayList();for(int i = 0;i  

5、多sheet导出

/** * 多sheet导出数据 * */@GetMapping("/manySheet")public void exportManySheet(HttpServletResponse response)throws IOException{OutputStream outputStream=response.getOutputStream();ExcelWriter writer = EasyExcel.write(outputStream, UserDO.class).excelType(ExcelTypeEnum.XLSX).build();try {this.setExcelResponseProp(response, "用户列表");// 模拟根据条件在数据库分页查询数据for(int j = 1;j 

上一篇:使用npm包js-web-screen-shot做网页截图,可以对截图加文字,箭头等等,类似于微信截图

下一篇:HTML技巧,轻松实现导航栏固定在页面底部教程