spring boot集成EasyPOI做简单Excel的导入导出

1. 引入Easypoi坐标

 		<dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-spring-boot-starter</artifactId>
            <version>3.3.0</version>
        </dependency>

2. 数据库和Excel映射的实体类

@NoArgsConstructor
@AllArgsConstructor
@ToString
@Data
public class Employee implements Serializable {

    // name :Excel标题字段名称 width: 宽  height: 高
    @Excel(name = "员工编号", width = 10, height = 30)
    private Integer id;

    @Excel(name = "员工姓名", width = 20, height = 30)
    private String name;

    @Excel(name = "性别", width = 10, height = 30)
    private String gender;


    @Excel(name = "出生年月", width = 10, height = 30, format = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")  //以JSON返回给前端时时间要进行格式化处理
    private Date birthday;

    @Excel(name = "身份证号", width = 50, height = 30)
    private String idCard;

    @Excel(name = "婚姻状况", width = 10, height = 30)
    private String wedlock;


    private Integer nationId;
    @Excel(name = "民族", width = 10, height = 30)
    private String nationName;

    @Excel(name = "籍贯", width = 10, height = 30)
    private String nativePlace;


    private Integer politicId;
    @Excel(name = "政治面貌", width = 15, height = 30)
    private String politic;

    @Excel(name = "邮箱", width = 20, height = 30)
    private String email;

    @Excel(name = "电话号码", width = 20, height = 30)
    private String phone;

    @Excel(name = "联系地址", width = 10, height = 30)
    private String address;


    private Integer departmentId;
    @Excel(name = "所属部门", width = 10, height = 30)
    private String departmentName;


    private Integer jobLevelId;
    @Excel(name = "职称", width = 10, height = 30)
    private String jobLevelName;


    private Integer posId;
    @Excel(name = "职位", width = 10, height = 30)
    private String pos;

    @Excel(name = "聘用形式", width = 10, height = 30)
    private String engageForm;

    @Excel(name = "最高学历", width = 10, height = 30)
    private String tiptopDegree;

    @Excel(name = "所属专业", width = 10, height = 30)
    private String specialty;

    @Excel(name = "毕业院校", width = 10, height = 30)
    private String school;

    @Excel(name = "入职日期", width = 10, height = 30, format = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date beginDate;

    @Excel(name = "在职状态", width = 10, height = 30)
    private String workState;

    @Excel(name = "工号", width = 10, height = 30)
    private String workId;

    @Excel(name = "合同期限", width = 10, height = 30)
    private Double contractTerm;

    @Excel(name = "转正日期", width = 10, height = 30, format = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date conversionTime;

    @Excel(name = "离职日期", width = 10, height = 30, format = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date notworkDate;

    @Excel(name = "合同起始日期", width = 10, height = 30, format = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date beginContract;

    @Excel(name = "合同终止日期", width = 10, height = 30, format = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date endContract;

    @Excel(name = "工龄", width = 10, height = 30)
    private Integer workAge;

    private Nation nation;

    private Politicsstatus politicsstatus;

    private Department department;

    private JobLevel jobLevel;

    private Position position;
}

3. POI工具类

public  class  POIUtils  {
    

    /*
     * @methodName: export
     * @description excel 导出操作
     * @param:  data:实体类数据
     *          tClass:映射的实体类class
     *          excelName:导出的excel名称
     *          sheetName: sheet名称
     *          isCreateHeadRows :是否有表头行
     *          style : 表格自定义样式
     * @return: ResponseEntity
     * @createdAt 11:23 2020/8/5 0005
     * @version 1.0.0
     **/
    public static <R> ResponseEntity<byte[]> export(List<R> data, Class<R> tClass, String excelName, String sheetName
        , boolean isCreateHeadRows, Class<? extends AbstractExcelExportStyler> style) throws UnsupportedEncodingException {

        ExportParams exportParams = new ExportParams();
        exportParams.setSheetName(sheetName);
        exportParams.setCreateHeadRows(isCreateHeadRows);
        exportParams.setTitle(sheetName); //表格名称
        if (style!=null){
            exportParams.setStyle(style);
        }else {
            exportParams.setStyle(ExcelExportStylerImpl.class); //设置表格的style样式  自定义Style,并实现相应的接口
        }

        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, tClass, data);
        ByteArrayOutputStream fos = new ByteArrayOutputStream();
        try {

            workbook.write(fos);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {

                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentDispositionFormData("attachment", new String(String.format("%s.xls", excelName).getBytes(
            "UTF-8"), "ISO-8859-1"));
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<byte[]>(fos.toByteArray(), headers, HttpStatus.CREATED);
    }

	/*
	     * @methodName: importExcel
	     * @description excel 导入操作
	     * @param: file 需要导入的文件
	     *         titleRows 表格标题行数,默认0
	     *         headerRows 表头行数,默认1
	     *         pojoClass 映射的实体类class
	     * @return: List 导入解析成功的数据
	     * @createdAt 11:30 2020/8/5 0005
	     * @version 1.0.0
	     **/
    public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass){
        if (file == null){
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows); //标题行有几行
        params.setHeadRows(headerRows); //表头行有几行
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params); //导入成功的数据
        }catch (NoSuchElementException e){
            throw e;
        } catch (Exception e) {
            e.printStackTrace();

        }
        return list;
    }
}

3.1自定义Excel样式

/*
 * @className: ExcelExportStylerImpl
 * @description 设置Excle的样式
 * @since JDK1.8
 * @author ljh
 * @createdAt  2020/8/4 0004
 * @version 1.0.0
 **/
public class ExcelExportStylerImpl extends AbstractExcelExportStyler
    implements IExcelExportStyler {
    public ExcelExportStylerImpl(Workbook workbook) {
        super.createStyles(workbook);
    }

    /*
     * @methodName:
     * @description 设置标题样式
     * @param:
     * @return:
     * @createdAt 15:26 2020/8/4 0004
     * @version 1.0.0
     **/
    @Override
    public CellStyle getTitleStyle(short color) {
        CellStyle titleStyle = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setBold(true); //字体加粗
        titleStyle.setFont(font);
        titleStyle.setAlignment(HorizontalAlignment.CENTER); //水平居中
        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER); //垂直居中
        titleStyle.setFillForegroundColor(IndexedColors.BLUE.getIndex()); //单元格背景颜色
        titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        titleStyle.setBorderRight(BorderStyle.THIN); //右边框
        titleStyle.setAlignment(CellStyle.ALIGN_CENTER);
        titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        titleStyle.setWrapText(true);
        return titleStyle;
    }

    @Override
    public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) {
        CellStyle style = workbook.createCellStyle();
        style.setAlignment(CellStyle.ALIGN_CENTER);
        style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        style.setDataFormat(STRING_FORMAT);
        if (isWarp) {
            style.setWrapText(true);
        }
        return style;
    }

    @Override
    public CellStyle getHeaderStyle(short color) {
        CellStyle titleStyle = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setFontHeightInPoints((short) 12);
        titleStyle.setFont(font);
        titleStyle.setAlignment(CellStyle.ALIGN_CENTER);
        titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        return titleStyle;
    }

    @Override
    public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) {
        CellStyle style = workbook.createCellStyle();
        style.setAlignment(CellStyle.ALIGN_CENTER);
        style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        style.setDataFormat(STRING_FORMAT);
        if (isWarp) {
            style.setWrapText(true);
        }
        return style;
    }
}

4. Excel导出

4.1 后端接口

@GetMapping("/employee/basic/export")
public ResponseEntity<byte[]> export() throws IOException {
        //查出所有需要导出的数据
        List<Employee> list = (List<Employee>) getAllEmployee(1, Integer.MAX_VALUE, null).getList();

        for (Employee employee : list) {
            employee.setNationName(employee.getNation().getName());
            employee.setPos(employee.getPosition().getName());
            employee.setJobLevelName(employee.getJobLevel().getName());
            employee.setDepartmentName(employee.getDepartment().getName());
            employee.setPolitic(employee.getPoliticsstatus().getName());
        }
        return POIUtils.export(list, Employee.class, "员工信息表", "员工信息", true, null);

    }

4.2 前端

window.open("/employee/basic/export", '_parent')  //在当前页面打开文件(文件下载)

5. 导入操作

5.1 后端接口

/*
     * @methodName: importEmp
     * @description Excel导入
     * @param: file 前端的导入的文件名称要和后一致
     * @return: 
     * @createdAt 11:44 2020/8/5 0005
     * @version 1.0.0
     **/
     @PostMapping("/employee/basic/import")
    public Boolean importEmp(MultipartFile file) {

        List<Employee> employees = POIUtils.importExcel(file, 1, 1, Employee.class);

        List<Nation> allNation = nationMapper.getAllNation();

        List<Politicsstatus> allPoliticsStatus = politicsstatusMapper.getAllPoliticsStatus();

        List<Department> departments = departmentMapper.queryAllDeptName();

        List<JobLevel> jobLevels = jobLevelMapper.queryJobs();

        List<Position> positions = positionMapper.queryPosition();

        LinkedList<Employee> newList = new LinkedList<>();


        //这里因为相关字段库里存的是关联ID 而要从本地导入的表里存的是相关的名称 所以要在这里做相应处理(将Excel表里名称转换为对应ID)
        for (Employee employee : employees) {
            employee.setId(null); //数据库主键自增
            for (Nation nation : allNation) {
                if (nation.getName().equals(employee.getNationName())) {
                    employee.setNationId(nation.getId());
                    break;
                }
            }

            for (Politicsstatus politicsStatus : allPoliticsStatus) {
                if (politicsStatus.getName().equals(employee.getPolitic())) {
                    employee.setPoliticId(politicsStatus.getId());
                    break;
                }
            }

            for (Department department : departments) {
                if (department.getName().equals(employee.getDepartmentName())) {
                    employee.setDepartmentId(department.getId());
                    break;
                }
            }

            for (JobLevel jobLevel : jobLevels) {
                if (jobLevel.getName().equals(employee.getJobLevelName())) {
                    employee.setJobLevelId(jobLevel.getId());
                    break;
                }
            }

            for (Position position : positions) {
                if (position.getName().equals(employee.getPos())) {
                    employee.setPosId(position.getId());
                    break;
                }
            }
            newList.add(employee);
        }
        int i = employeeMapper.batchInsert(newList); //批量插入数据库

        if (i == newList.size()) {
            return true;
        }
        return false;
    }

5.2 前端

<!--这里使用的是element ui的upload组件 相关属性可参考element ui 官网-->
				<el-upload style="display: inline-flex ;margin-right: 5px"
                           class="upload-demo"
                           action="/employee/basic/import"
                           :multiple="false"
                           :show-file-list="false"
                           :on-success="onSuccess"
                           :on-progress="onProgress"
                           :on-error="onFail"
                           :disabled="disabled">
                    <el-button type="success">
                        <i :class="el_icon" aria-hidden="true"></i>
                        {{importSource}}
                    </el-button>
                </el-upload>

data(){
	return{
				importSource: "导入数据",
                el_icon: 'el-icon-upload2',
                disabled: false
	}
}

methods:{
/*导入成功的回调*/
onSuccess() {

                this.importSource = "导入数据"
                this.el_icon = 'el-icon-upload2'
                this.disabled = false
                this.$message({
                    message: '导入成功',
                    type: 'success'
                });
            },
            /*导入中回调*/
            onProgress() {
                this.importSource = "导入中"
                this.el_icon = 'el-icon-loading'
                this.disabled = true
            },
            /*导入失败的回调*/
            onFail() {
                this.importSource = "导入数据"
                this.el_icon = 'el-icon-upload2'
                 this.disabled = false
                this.$message({
                    message: '导入失败',
                    type: 'error'
                });
            }
     }

6. 注意

在导入easypoi pom坐标后启动项目会报错 需要在yml文件中设置

Description:

The bean 'beanNameViewResolver', defined in class path resource [cn/afterturn/easypoi/configuration/EasyPoiAutoConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class] and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
spring:
  main:
    allow-bean-definition-overriding: true

你可能感兴趣的:(EasyPOI,excel,poi,mysql)