基于Springboot使用EasyExcel实现Excel操作

EasyExcel使用

一、简介

EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。EasyExcel官方文档地址(https://easyexcel.opensource.alibaba.com/)

二、使用

1、引入依赖

    <dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>easyexcel</artifactId>
			<version>3.1.1</version>
	</dependency>

2、创建实体类

package com.genersoft.iot.vmp.info.entity;

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.genersoft.iot.vmp.info.utils.ExcelSelected;
import com.genersoft.iot.vmp.info.utils.HouseStatusConverter;
import com.genersoft.iot.vmp.info.utils.TypeConverter;
import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.data.annotation.Transient;

import java.util.List;

/**
 * @author xxx
 * @date 2023年04月03日 9:57
 *
 * 房屋基本信息表
 */

@ColumnWidth(12)
public class HouseBaseinfo {

    @Schema(description = "主键")
    @ExcelIgnore
    private Integer id;

    @Schema(description = "市级智慧小区ID")
    @ExcelIgnore
    private String communityId;

    @Transient
    @Schema(description = "市级平台内小区id")
    @ExcelProperty(index = 0,value = "小区名称")
    private String communityName;

    @Schema(description = "唯一标识(hash值)")
    @ExcelIgnore
    private String evtId;

    @Schema(description = "楼栋号")
    @ExcelProperty(index = 1,value = "楼栋号")
    private Integer number;

    @Schema(description = "单元号")
    @ExcelProperty(index = 2,value = "单元号")
    private Integer unit;

    @Schema(description = "楼层")
    @ExcelProperty(index = 3,value = "楼层")
    private Integer floor;

    @Schema(description = "门牌号")
    @ExcelProperty(index = 4,value = "门牌号")
    private Integer room;

    @Schema(description = "居住现状(1、自用 2、租用 3、自住 4、借用 5、空置 6、家庭租住 7、群租)")
    @ExcelSelected(source = {"自用","租用","自住","借用","空置","家庭租住","群租"})
    @ExcelProperty(index = 5,value = "居住现状",converter = HouseStatusConverter.class)
    private Integer status;

    @ExcelSelected(source = {"单元(公寓)楼","简子楼","别墅","平房","自建楼","四合院","其他"})
    @Schema(description = "房屋类别(1、单元(公寓)楼 2、简子楼 3、别墅 4、平房 5、自建楼 6、四合院 7、其他)")
    @ExcelProperty(index = 6,value = "房屋类别",converter = TypeConverter.class)
    private Integer type;

    @Schema(description = "房屋间数")
    @ExcelProperty(index = 7,value = "房屋间数")
    private Integer bedRoom;

    @Schema(description = "房屋面积")
    @ExcelProperty(index = 8,value = "房屋面积")
    private Integer area;

    @Schema(description = "实有人口")
    @ExcelProperty(index = 9,value = "实有人口")
    private Integer people;

    @Schema(description = "标准地址")
    @ExcelProperty(index = 10,value = "标准地址")
    @ColumnWidth(50)
    private String address;

    @Schema(description = "创建时间")
    @ExcelIgnore
    private Long createTime;

    @Schema(description = "更新时间")
    @ExcelIgnore
    private Long updateTime;

}


实体类对应的Excel表格

小区名称楼栋号单元号楼层门牌号居住现状房屋类别房屋间数房屋面积实有人口标准地址

注解解释

@ExcelProperty 用于设置实体类字段在excel中展示

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ExcelProperty {
    //用于设置Excel列名
    String[] value() default {""};
    //用于设置Excel列序号
    int index() default -1;
    //用于设置Excel列序号,优先级高于index
    int order() default Integer.MAX_VALUE;
    //枚举类型字段转换器
    Class<? extends Converter<?>> converter() default AutoConverter.class;

    /** @deprecated */
    @Deprecated
    String format() default "";
}

@ExcelSelected 用于设置下拉列表

@Documented
@Retention(RetentionPolicy.RUNTIME)  //注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
@Target(ElementType.FIELD)  //用此注解用在属性上。
public @interface ExcelSelected {
    /**
     * 固定下拉内容
     */
    String[] source() default {};

    /**
     * 动态下拉内容
     */
    Class<? extends ExcelDynamicSelect>[] sourceClass() default {};

    /**
     * 设置下拉框的起始行,默认为第二行
     */
    int firstRow() default 1;

    /**
     * 设置下拉框的结束行,默认为最后一行
     */
    int lastRow() default 0x10000;
}

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

@ColumnWidth(12) 设置列宽

@ContentRowHeight(15) 设置内容的行高

@HeadRowHeight(25) 设置表头的行高

3、创建枚举类

package com.genersoft.iot.vmp.info.entity;

public enum HouseType {

    ONE(1,"单元(公寓)楼"),
    TWO(2,"简子楼"),
    THREE(3,"别墅"),
    FOUR(4,"平房"),
    FIVE(5,"自建楼"),
    SIX(6,"四合院"),
    SEVEN(7,"其他")
    ;
    // 成员变量
    private Integer code;
    private String houseType;

    HouseType(Integer code, String houseType) {
        this.houseType = houseType;
        this.code = code;
    }

    public String getHouseType() {
        return houseType;
    }

    public Integer getCode() {
        return code;
    }
}

4、创建转换器

package com.genersoft.iot.vmp.info.utils;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ReadConverterContext;
import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.genersoft.iot.vmp.info.entity.HouseType;

/**
 * 房屋类型转换器
 * @author xxx
 * @date 2023年04月17日 9:08
 */
public class TypeConverter implements Converter<Integer> {
    @Override
    public Class<?> supportJavaTypeKey() {
        //对象属性类型
        return Integer.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        //CellData属性类型
        return CellDataTypeEnum.STRING;
    }

    @Override
    public Integer convertToJavaData(ReadConverterContext<?> context) throws Exception {
        //CellData转对象属性
        String cellStr = context.getReadCellData().getStringValue();
        if (StrUtil.isEmpty(cellStr)) return null;
        if (HouseType.ONE.getHouseType().equals(cellStr)) {
            return HouseType.ONE.getCode();
        } else if (HouseType.TWO.getHouseType().equals(cellStr)) {
            return HouseType.TWO.getCode();
        } else if (HouseType.THREE.getHouseType().equals(cellStr)) {
            return HouseType.THREE.getCode();
        } else if (HouseType.FOUR.getHouseType().equals(cellStr)) {
            return HouseType.FOUR.getCode();
        } else if (HouseType.FIVE.getHouseType().equals(cellStr)) {
            return HouseType.FIVE.getCode();
        } else if (HouseType.SIX.getHouseType().equals(cellStr)) {
            return HouseType.SIX.getCode();
        } else if (HouseType.SEVEN.getHouseType().equals(cellStr)) {
            return HouseType.SEVEN.getCode();
        } else {
            return null;
        }
    }

    @Override
    public WriteCellData<?> convertToExcelData(WriteConverterContext<Integer> context) throws Exception {
        //对象属性转CellData
        Integer cellValue = context.getValue();
        if (cellValue == null) {
            return new WriteCellData<>("");
        }
        if (cellValue.equals(HouseType.ONE.getCode())) {
            return new WriteCellData<>(HouseType.ONE.getHouseType());
        } else if (cellValue.equals(HouseType.TWO.getCode())) {
            return new WriteCellData<>(HouseType.TWO.getHouseType());
        } else if (cellValue.equals(HouseType.THREE.getCode())) {
            return new WriteCellData<>(HouseType.THREE.getHouseType());
        } else if (cellValue.equals(HouseType.FOUR.getCode())) {
            return new WriteCellData<>(HouseType.FOUR.getHouseType());
        } else if (cellValue.equals(HouseType.FIVE.getCode())) {
            return new WriteCellData<>(HouseType.FIVE.getHouseType());
        } else if (cellValue.equals(HouseType.SIX.getCode())) {
            return new WriteCellData<>(HouseType.SIX.getHouseType());
        } else if (cellValue.equals(HouseType.SEVEN.getCode())) {
            return new WriteCellData<>(HouseType.SEVEN.getHouseType());
        } else {
            return new WriteCellData<>("");
        }
    }
}

5、下载导入模版

@Operation(summary = "下载房屋信息导入模板")
@GetMapping("downloadTemplate")
public void downloadTemplate(HttpServletResponse response) throws IOException {
    houseBaseinfoService.downloadTemplate(response);
}

public void downloadTemplate(HttpServletResponse response) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        List<HouseBaseinfo> houseBaseinfos = new ArrayList<>();
        HouseBaseinfo houseBaseinfo = new HouseBaseinfo();
        houseBaseinfo.setCommunityName("智慧小区");
        houseBaseinfo.setNumber(1);
        houseBaseinfo.setUnit(2);
        houseBaseinfo.setFloor(3);
        houseBaseinfo.setRoom(1);
        houseBaseinfo.setStatus(1);
        houseBaseinfo.setType(1);
        houseBaseinfo.setBedRoom(3);
        houseBaseinfo.setArea(89);
        houseBaseinfo.setPeople(3);
        houseBaseinfo.setAddress("不用填,后台会自动生成!");
        houseBaseinfos.add(houseBaseinfo);
        try {
            String fileName = URLEncoder.encode("房屋信息导入模板", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
            WriteSheet writeSheet = EasyExcelUtil.writeSelectedSheet(HouseBaseinfo.class, 0, "房屋信息");
            excelWriter.write(houseBaseinfos, writeSheet);
            excelWriter.finish();
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = MapUtils.newHashMap();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
        }

    }

6、批量导入

@Operation(summary = "批量导入房屋信息")
@PostMapping("importExcel")
public Object importExcel(HttpServletRequest request, HttpServletResponse response, @RequestBody MultipartFile file) throws IOException {
    return houseBaseinfoService.importExcel(file);
}

public Object importExcel(MultipartFile file) throws IOException{
        List<HouseBaseinfo> excelList = null;
        String validate = "";
        //校验文件大小 100M
        boolean size = FileUtil.checkFileSize(file.getSize(), 100, "M");
        if(size == false){
            //文件过大啦,只能100M
            return WVPResult.fail(ErrorCode.ERROR100.getCode(), "文件过大啦,不能超过100M");
        }
        //excel读取数据
        excelList = EasyExcel.read(new BufferedInputStream(file.getInputStream())).head(HouseBaseinfo.class).sheet().doReadSync();
//        if (ExcelList.size() > 1000) {
//            //最多导入1000条哦
//        }
//        // excel数据校验
//        validate = ValidatorUtils.beanValidate(ExcelList);
//        if(!validate.equals("success")){
//            //参数异常提示  如:姓名不能为空哦~
//        }
        //总记录数
        Integer number = 0;
        for (HouseBaseinfo houseBaseinfo : excelList) {
            //根据小区名称查询小区id
            CommunityBaseinfo communityBaseinfo = communityBaseinfoMapper.getCommunityBaseinfoByCommunityName(houseBaseinfo.getCommunityName());
            if(communityBaseinfo == null){
                return WVPResult.fail(ErrorCode.ERROR100.getCode(), "请检查小区名字是否正确");
            }else{
                houseBaseinfo.setCommunityId(communityBaseinfo.getCommunityId());
            }
            Integer result = Integer.valueOf(addHouseBaseinfo(houseBaseinfo).toString());
            number = number+result;
        }
        return WVPResult.success(String.format("成功导入%s条房屋信息",number));
    }
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
是的,Spring Boot 可以使用 EasyExcel 库来上传 Excel 文件。EasyExcel 是一个基于 Java 的简单、高效的 Excel 处理工具,支持读写 Excel 文件,并且速度非常快。以下是使用 Spring Boot 和 EasyExcel 实现上传 Excel 文件的步骤: 1. 添加 EasyExcel 依赖 在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.1.6</version> </dependency> ``` 2. 创建 Excel 文件上传接口 在 Spring Boot 中创建一个接口,用于上传 Excel 文件。例如: ```java @PostMapping("/upload") public String upload(MultipartFile file) throws IOException { InputStream inputStream = file.getInputStream(); EasyExcel.read(inputStream, DemoData.class, new DemoDataListener()).sheet().doRead(); return "success"; } ``` 3. 创建数据实体类 在 Spring Boot 中创建一个数据实体类,用于存储 Excel 文件中的数据。例如: ```java @Data @NoArgsConstructor @AllArgsConstructor public class DemoData { @ExcelProperty(value = "字符串标题", index = 0) private String string; @ExcelProperty(value = "日期标题", index = 1) private Date date; @ExcelProperty(value = "数字标题", index = 2) private Double doubleData; } ``` 4. 创建数据监听器类 在 Spring Boot 中创建一个数据监听器类,用于处理 Excel 文件中的数据。例如: ```java public class DemoDataListener extends AnalysisEventListener<DemoData> { private List<DemoData> list = new ArrayList<>(); @Override public void invoke(DemoData data, AnalysisContext context) { list.add(data); } @Override public void doAfterAllAnalysed(AnalysisContext context) { // 处理数据 System.out.println(list); } } ``` 5. 创建 Excel 模板文件 在 Spring Boot 中创建一个 Excel 模板文件,用于上传数据。例如: | 字符串标题 | 日期标题 | 数字标题 | | ---------- | ---------- | -------- | | Hello | 2022/01/01 | 1.1 | | World | 2022/01/02 | 2.2 | 6. 启动应用程序并测试 启动 Spring Boot 应用程序并测试上传 Excel 文件功能。可以使用 Postman 等工具进行测试。 以上就是使用 Spring Boot 和 EasyExcel 实现上传 Excel 文件的步骤。希望对你有所帮助!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值