java实现excel导入与导出(总结与实现)

java实现excel导入与导出(总结与实现)

SpringBoot项目集成

1.创建一个springboot项目,我所使用的版本是2.2.4
2.导入EasyExcel的pom依赖,和lombok依赖。

<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>easyexcel</artifactId>
		<version>2.2.11</version>
</dependency>
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.18.22</version>
</dependency>

EasyExcel版本选择
在这里插入图片描述

全部使用教程可以EasyExcel官网查看EasyExcel官方文档

一.excle文件导出下载

实体类的创建

这里创建一个实体类,用于封装数据

  • 常用注解说明
注解参数说明
ExcelIgnore导出时忽略该字段
ExcelPropertyvalue,index,order,convertervalue设置该列的名称,order优先级高于value,会根据order的顺序来匹配实体和excel中数据的顺序index 优先级高于value和order,会根据index直接指定写到第几列,默认根据成员变量排序。value指定写入的名称,默认成员变量的名字,多个value可以参照快速开始中的复杂头 ,converter 是自定义转换器
DateTimeFormatstring日期的格式化
ColumnWidth(20)int设置表格列的宽度为20
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.Date;

@Data
public class PromptInformationDown {

    //提示信息表id
    @TableId
    //导出时忽略该字段
    @ExcelIgnore
    private Long id;

    //角色id(比如经理,财务之类)
    //设置该列的名称为角色
    @ExcelProperty("角色")
    @ColumnWidth(20)
    private Long roleId;

	//自定义转换器
    @ExcelProperty(value ="提示信息类型" ,converter = TipEnum.class)
    @ColumnWidth(20)
    //提示信息(员工转正1,员工合同到期2,员工退休3,请假4)
    private Integer tip;

    @ExcelProperty("员工名")
    @ColumnWidth(20)
    //禁戒的员工名
    private String employeeName;

    @ColumnWidth(20)
    @ExcelProperty("提示创建时间")
    @DateTimeFormat("yyyy-MM-dd")
    //创建时间
    private Date creatTime;

    @ColumnWidth(20)
    @ExcelProperty("提示最后期限")
    @DateTimeFormat("yyyy-MM-dd")
    //最后期限
    private Date lastTime;

    @ColumnWidth(20)
    @ExcelProperty("最后处理时间")
    @DateTimeFormat("yyyy-MM-dd")
    //修改时间
    private Date updateTime;
}

自定义转换器
转换器用于将自定义的特殊数字转换成相对应的字符(例如:数据库0,1分别代表男女进行存储,通过转换器在excle中显示的将不是0,1,而是相对应的男女)
注意:不同版本的convertToJavaData,convertToExcelData有些许的不同

package com.wedu.modules.excleUpOrDo;

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty;

public class TipEnum implements Converter<Integer> {

    //提示信息(员工转正1,员工合同到期2,员工退休3,请假4)
    private static final String ONE="员工转正";
    private static final String TWO="合同到期";
    private static final String TREE="员工退休";
    private static final String FOUR="请假";

    @Override
    public Class supportJavaTypeKey() {
        return Integer.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    @Override
    public Integer convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        // 从Cell中读取数据
        String gender = cellData.getStringValue();
        // 判断Excel中的值,将其转换为预期的数值
        if (ONE.equals(gender)) {
            return 1;
        } else if (TWO.equals(gender)) {
            return 2;
        }else if (TREE.equals(gender)) {
            return 3;
        }else if (FOUR.equals(gender)) {
            return 4;
        }
        return null;
    }

    @Override
    public CellData convertToExcelData(Integer integer, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        // 判断实体类中获取的值,转换为Excel预期的值,并封装为CellData对象
        if (integer == null) {
            return new CellData<>("");
        } else if (integer == 1) {
            return new CellData<>(ONE);
        } else if (integer == 2) {
            return new CellData<>(TWO);
        }else if (integer == 3) {
            return new CellData<>(TREE);
        }else if (integer == 4) {
            return new CellData<>(FOUR);
        }
        return new CellData<>("");
    }
}


数据库数据封装

这里将数据库所得到的数据封装到PromptInformationDown 这个excle的实体类中
这里我使用的是Mybatis Plus去获取数据库中的数据,在service层中进行业务逻辑代码的实现。

    excle导出接口
    @Override
    public List<PromptInformationDown> getAllMember() {
        List<PromptInformationDown> list = new ArrayList<>();
        //Mybatis Plus自带的list方法,获取所有数据封装到实体类中返回实体类的列表
        List<PromptInformationEntity> list1 = this.list();
        //通过循环将所得到的数据封装到PromptInformationDown 中
        list1.stream().forEach(a -> {
            PromptInformationDown d = new PromptInformationDown();
            d.setCreatTime(a.getCreatTime());
            d.setEmployeeId(a.getEmployeeId());
            d.setEmployeeName(a.getEmployeeName());
            d.setId(a.getId());
            d.setInformationId(a.getInformationId());
            d.setLastTime(a.getLastTime());
            d.setRoleId(a.getRoleId());
            d.setStatus(a.getStatus());
            d.setTip(a.getTip());
            d.setUpdateTime(a.getUpdateTime());
            //将装好的实体类添加进总list中
            list.add(d);
        });

        return list;
    }

导出实现

这里实现是在controller中进行实现的

package com.wedu.modules.excleUpOrDo;

import com.alibaba.excel.EasyExcel;
import com.wedu.modules.sys.service.PromptInformationService;
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.RequestPart;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@Controller
@RequestMapping("/excle")
public class ExcleUpOrDoController {
    @Autowired
    PromptInformationService informationService;

    //文件下载
    @PostMapping("/get")
    public void getExcle(HttpServletResponse response) throws IOException {
        List<PromptInformationDown> members = informationService.getAllMember();

        // 设置文本内省
        response.setContentType("application/vnd.ms-excel");
        // 设置字符编码
        response.setCharacterEncoding("utf-8");
        // 设置响应头
        response.setHeader("Content-disposition", "attachment;filename=demo.xlsx");
        EasyExcel.write(response.getOutputStream(), PromptInformationDown.class)
                .sheet("消息列表").doWrite(members);
    }

}

测试

通过ApiPost软件进行测试
在这里插入图片描述
下载之后会得到表格
在这里插入图片描述

excle表格的各种样式

这里我们写一个类CustomSheetWriteHandler类,用于美化excle表格

  • 这里我将以下拉框举例子(该代码是直接cv上方官方文档中的代码并添加了一些所需,如果需要其他格式,可以去官方文档中查找使用
package com.wedu.modules.excleUpOrDo;

import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 自定义拦截器.对第一列第一行和第二行的数据新增下拉框,显示 测试1 测试2
 *
 * @author Jiaju Zhuang
 */
public class CustomSheetWriteHandler implements SheetWriteHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(CustomSheetWriteHandler.class);

    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        LOGGER.info("第{}个Sheet写入成功。", writeSheetHolder.getSheetNo());

        // 区间设置 第一列第一行和第二行的数据。由于第一行是头,所以第一、二行的数据实际上是第二三行
        //这里1048575是行最大数,超出有可能会报错
        CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 1048575, 1, 1);
        DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper();
        //下拉框中的数据选项
        DataValidationConstraint constraint = helper.createExplicitListConstraint(new String[] {"员工转正", "合同到期","员工退休","请假"});
        DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
        writeSheetHolder.getSheet().addValidationData(dataValidation);
    }
}

这里的controller层需要添加一点东西,用于使用该类的渲染

    //文件下载
    @PostMapping("/get")
    public void getExcle(HttpServletResponse response) throws IOException {
        List<PromptInformationDown> members = informationService.getAllMember();

        // 设置文本内省
        response.setContentType("application/vnd.ms-excel");
        // 设置字符编码
        response.setCharacterEncoding("utf-8");
        // 设置响应头
        response.setHeader("Content-disposition", "attachment;filename=demo.xlsx");
        EasyExcel.write(response.getOutputStream(), PromptInformationDown.class)
//---------------------------------添加下面这句话进行调用----------------------------------
                .registerWriteHandler(new CustomSheetWriteHandler())
//---------------------------------------------------------------------------------------
                .sheet("消息列表").doWrite(members);
    }

直接展示结果
在这里插入图片描述

二.文件导入

controller层接口

文件导入会将数据重新分装进导出的实体类中,如果要使用的话可以将该数据封装进自己所需的实体类中

package com.wedu.modules.excleUpOrDo;

import com.alibaba.excel.EasyExcel;
import com.wedu.modules.sys.service.PromptInformationService;
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.RequestPart;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@Controller
@RequestMapping("/excle")
public class ExcleUpOrDoController {
    @Autowired
    PromptInformationService informationService;

    //文件导入
    @PostMapping("/uplode")
    public void uplodeExcle(@RequestPart("file")MultipartFile file) throws  IOException {
    
        List<PromptInformationDown> list = EasyExcel.read(file.getInputStream())
                .head(PromptInformationDown.class)
                .sheet()
                .doReadSync();
        for (PromptInformationDown member : list) {
        //输出封装完成的数据
            System.out.println(member.setPromptInformationEntity());
        }

    }

实体类封装

我在导出的实体类PromptInformationDown中加入了一个封装方法

//将文件类进行封装成实体类
    public PromptInformationEntity setPromptInformationEntity(){
        PromptInformationEntity d=new PromptInformationEntity();
        d.setCreatTime(this.getCreatTime());
        d.setEmployeeId(this.getEmployeeId());
        d.setEmployeeName(this.getEmployeeName());
        d.setId(this.getId());
        d.setInformationId(this.getInformationId());
        d.setLastTime(this.getLastTime());
        d.setRoleId(this.getRoleId());
        d.setStatus(this.getStatus());
        d.setTip(this.getTip());
        d.setUpdateTime(this.getUpdateTime());

        return d;
    }

进行测试

在这里插入图片描述
这里报错是因为没有返回的响应数据,不影响
后端得到数据
在这里插入图片描述

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值