POI报表导出(二)POI报表导入

一. 功能描述

实现批量导入员工功能,页面端上传excel表格,服务端解析表格获取数据,批量新增用户

二. 搭建环境

pom文件中导入依赖

<!--POI-->        
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
     <groupId>org.apache.poi</groupId>
     <artifactId>poi-ooxml-schemas</artifactId>
     <version>4.0.1</version>
</dependency>

三. 功能实现

1. 创建excel文件, “导入数据模板.xlsx”

2. 在User实体类中添加构造方法

//objs数据位置和excel上传位置一致
public User(Object[] objs, String companyId, String companyName){
    //默认手机号excel读取为字符串会存在科学记数法问题,转化处理
    this.mobile = objs[2].toString();
    this.username = objs[1].toString();
    this.createTime = new Date();
    this.timeOfEntry = (Date) objs[5];
    this.formOfEmployment = ((Double) objs[4]).intValue() ;
    this.workNumber = new DecimalFormat("#").format(objs[3]).toString();
    this.companyId = companyId;
    this.companyName = companyName;
    this.departmentId = objs[6].toString(); //部门编码 != 部门id
}

由于使用了lombok插件,故此要在类上加上注解@Getter, @Setter, @NoArgsConstructor

3. 在系统微服务UserController 中添加上传方法

//批量导入数据
@RequestMapping(value = "/user/import", method = RequestMethod.POST)
public Result importExcel(@RequestParam(name = "file") MultipartFile attachment)
        throws Exception {
    //根据上传流信息创建工作簿
    Workbook workbook = WorkbookFactory.create(attachment.getInputStream());
    //获取第一个sheet
    Sheet sheet = workbook.getSheetAt(0);
    List<User> users = new ArrayList<>();
    System.out.println("row: " + sheet.getLastRowNum());
    //从第二行开始获取数据
    for (int rowNum = 1; rowNum < sheet.getLastRowNum(); rowNum++) {
        Row row = sheet.getRow(rowNum);
        System.out.println("cell: " + row.getLastCellNum());
        Object objs[] = new Object[row.getLastCellNum()];
        //从第二列获取数据
        for (int cellNum = 1; cellNum < row.getLastCellNum(); cellNum++) {
            Cell cell = row.getCell(cellNum);
            objs[cellNum] = getValue(cell);
        }
        //根据每一列构造用户对象
        User user = new User(objs, companyId, companyName);
        user.setDepartmentId(objs[objs.length - 1].toString());
        users.add(user);
    }
    //第一个参数:用户列表,第二个参数:部门编码
    userService.save(users);
    return Result.SUCCESS();
}
public static Object getValue(Cell cell) {
    //1.获取到单元格的属性类型
    CellType cellType = cell.getCellType();
    //2.根据单元格数据类型获取数据
    Object value = null;
    switch (cellType) {
        case STRING:
            value = cell.getStringCellValue();
            break;
        case BOOLEAN:
            value = cell.getBooleanCellValue();
            break;
        case NUMERIC:
            if(DateUtil.isCellDateFormatted(cell)) {
                //日期格式
                value = cell.getDateCellValue();
             }else{
                //数字
                value = cell.getNumericCellValue();
             }
            break;
        case FORMULA: //公式
            value = cell.getCellFormula();
            break;
        default:
            break;
    }
    return value;
}

四. 由于使用了Eureka和Feign,需要配置Feign的客户端接口

1. 配置Feign的客户端接口

package com.ihrm.system.client;

import com.ihrm.common.entity.Result;
import com.ihrm.domain.company.Department;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * 声明接口,通过feign调用其它微服务
 */
@FeignClient("ihrm-company")
public interface DepartmentFeignClient {
    /**
     * 远程调用企业微服务,根据企业编码code和企业名称获取企业信息
     * @param code
     * @param companyId
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/company/department/search", method = RequestMethod.POST)
    public Department findByCode(@RequestParam(value = "code") String code, @RequestParam(value = "companyId") String companyId) throws Exception;
}

2. 在企业微服务中添加对应的接口

(1) Controller

@RequestMapping(value="/department/search", method = RequestMethod.POST)
public Department findByCode(@RequestParam(value="code") String code, @RequestParam(value="companyId") String companyId) {
    Department dept = departmentService.findByCode(code, companyId);
    return dept;
}

(2) Service

Department的Service:

/**
 * 根据部门编码和企业id查询部门
 */
public Department findByCode(String code, String companyId) {
    return departmentDao.findByCodeAndCompanyId(code,companyId);
}

User的Service:

@Transactional
public void save(List<User> users) throws Exception {
    for (User user : users) {
        //配置密码
        user.setPassword(new Md5Hash("123456",user.getMobile(),3).toString());
        //配置id
        user.setId(idWorker.nextId()+"");
        //其他基本属性
        user.setInServiceStatus(1);
        user.setEnableState(1);
        user.setLevel("user");
        //获取部门信息
        Department dept = departmentFeignClient.findByCode(user.getDepartmentId(), user.getCompanyId());
        if(dept != null) {
            user.setDepartmentId(dept.getId());
            user.setDepartmentName(dept.getName());
        }
        userDao.save(user);
    }
}

(3) DAO

import com.ihrm.domain.company.Department;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface DepartmentDao extends JpaRepository<Department, String> , JpaSpecificationExecutor<Department> {
    Department findByCodeAndCompanyId(String code, String companyId);
}

 五. 测试

1. 使用Postman调用该接口

2. 查看MySql数据库的数据

 

3. 注意:使用postman调用接口的时候一定要去掉头信息中的ContentType,否则会出现一些问题

猜你喜欢

转载自blog.csdn.net/qq_36662478/article/details/88210173