05 easyPoi的使用

使用easyPoi导出导入excel

1. 引入依赖

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

2. 使用方式

1. 简单的excel表格可以使用在实体类属性上添加注解使用

实体类

属性上有@Excel注解的将会作为列被导出到excel中,列的名称就是Excel注解中name属性

package com.ztbase.erp.domain.dto;

import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.handler.inter.IExcelDataModel;
import cn.afterturn.easypoi.handler.inter.IExcelModel;
import com.ztbase.erp.common.enums.JobRankEnums;
import com.ztbase.system.domain.dto.BaseDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.math.BigDecimal;

/**
 * <p>
 * 工资发放途径表
 * </p>
 *
 * @author shunyuM
 * @since 2022-04-21
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "SalaryWay对象", description = "工资发放途径表")
@Accessors(chain = true)
public class SalaryWayDTO extends BaseDTO implements IExcelDataModel, IExcelModel {

    private static final long serialVersionUID = 1L;

    private Integer rowNum;

    private String errorMsg;

    @ApiModelProperty(value = "员工姓名")
    @Excel(name = "员工姓名", orderNum = "2")
    private String employeeName;

    @ApiModelProperty(value = "月份")
    @Excel(name = "月份", orderNum = "1")
    private String months;

    @ApiModelProperty(value = "证件号码")
    @Excel(name = "身份证号", orderNum = "3", width = 20D)
    private String idCard;

    @ApiModelProperty(value = "手机号")
    @Excel(name = "手机号", orderNum = "4", width = 15D)
    private String mobile;

    @ApiModelProperty(value = "城市")
    @Excel(name = "城市", orderNum = "5")
    private String city;

    @ApiModelProperty(value = "岗位名称")
    @Excel(name = "岗位名称", orderNum = "6", width = 15D)
    private String jobName;

    @ApiModelProperty(value = "岗位职级")
    @Excel(name = "岗位级别", replace = {"初级_PRIMARY", "中级_INTERMEDIATE", "高级_SENIOR", "资深_VETERAN", "专家_EXPERT", "_EMPTY"},
            isImportField = "true", orderNum = "7")
    private JobRankEnums jobRank;

    @ApiModelProperty(value = "员工id")
    private Long employeeId;

    @ApiModelProperty(value = "员工状态:为0离职,为1正常,2试用")
    private Integer employeeStatus;

    @ApiModelProperty(value = "项目id")
    private Long projectId;

    @ApiModelProperty(value = "应发工资id")
    private Long payableSalaryId;

    @ApiModelProperty(value = "应发工资")
    @Excel(name = "应发工资", orderNum = "8")
    private BigDecimal payableSalary;

    @ApiModelProperty(value = "欣悦")
    @Excel(name = "欣悦", orderNum = "9")
    private BigDecimal xinYue;

    @ApiModelProperty(value = "易才")
    @Excel(name = "易才", orderNum = "10")
    private BigDecimal yiCai;

    @ApiModelProperty(value = "邦芒")
    @Excel(name = "邦芒", orderNum = "11")
    private BigDecimal bangMang;

    @ApiModelProperty(value = "北京外服")
    @Excel(name = "北京外服", orderNum = "12")
    private BigDecimal beijingForeignService;

    @ApiModelProperty(value = "云账户")
    @Excel(name = "云账户", orderNum = "13")
    private BigDecimal cloudAccount;

    @Override
    public void setRowNum(Integer rowNum) {
        this.rowNum = rowNum;
    }

    @Override
    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }
}
接收前端请求

导入

	@PostMapping(value = "/import")
    @ApiOperation(tags = "导入工资发放途径", value = "导入工资发放途径")
    public R<ImportResultDTO<SalaryWayDTO>> importInsurance(@RequestParam("file") MultipartFile file) throws Exception {
        ImportParams params = new ImportParams();
        params.setTitleRows(0);
        params.setHeadRows(1);
        params.setNeedVerify(true); // 开启校验
        params.setVerifyHandler(salaryWayImportVerifyHandler); // todo 在这里可以设置数据的校验格式
        ExcelImportResult<SalaryWayDTO> result = ExcelImportUtil.importExcelMore(file.getInputStream(), SalaryWayDTO.class, params);
        salaryWayService.importSalaryWay(result.getList());

        ImportResultDTO<SalaryWayDTO> resultDTO = new ImportResultDTO<>(result);
        return R.success(resultDTO);
    }

导出

	@GetMapping("/export")
    @ApiOperation(tags = "导出应发工资表", value = "导出应发工资表")
    public void exportExcel(SalaryWayQuery salaryWayQuery, HttpServletRequest request, HttpServletResponse response) {
        // salaryWayQuery.setSize(999);
        // salaryWayQuery.setCurrent(1L);
        // Page<SalaryWayDTO> salaryWayPage = salaryWayService.listEditPage(salaryWayQuery);
        // List<SalaryWayDTO> salaryWayDTOList = salaryWayPage.getRecords();
        List<SalaryWayDTO> salaryWayDTOList = new ArrayList<>();
        salaryWayDTOList.add(new SalaryWayDTO());
        if (CollectionUtils.isEmpty(salaryWayDTOList)) {
            return;
        }
        FileExportUtils exportUtils = FileExportUtils.getInstance();
        // todo 设置响应给浏览器的是文件
        exportUtils.exportPrepare("应发工资表.xlsx", request, response);
        try (OutputStream os = response.getOutputStream()) {
            // todo 调用FileExportUtils进行文件导出
            exportUtils.exportExcel(null, "应发工资表", SalaryWayDTO.class, salaryWayDTOList, os);
        } catch (IOException e) {
            throw BizException.build(ResultEnum.IO_OPERATION_FAILED);
        }
    }
导入时校验导入的数据
package com.ztbase.erp.handle.excel;

import cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHandlerResult;
import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;
import com.ztbase.erp.domain.dto.SalaryWayDTO;
import com.ztbase.erp.domain.entity.Employee;
import com.ztbase.erp.domain.entity.PayableSalary;
import com.ztbase.erp.service.EmployeeService;
import com.ztbase.erp.service.PayableSalaryService;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Objects;
import java.util.StringJoiner;

/**
 * @Author: shunyuM
 * @Date: 2022-11-05 18:45
 * @Description: 工资发放途径导入校验, 校验每一行数据
 */
@Component
public class SalaryWayImportVerifyHandler implements IExcelVerifyHandler<SalaryWayDTO> {

    @Resource
    private EmployeeService employeeService;
    @Resource
    private PayableSalaryService payableSalaryService;

    @Override
    public ExcelVerifyHandlerResult verifyHandler(SalaryWayDTO salaryWay) {
        StringJoiner errorMsg = new StringJoiner(";");
        Employee employee = employeeService.getByIdCard(salaryWay.getIdCard());
        if (Objects.isNull(employee)) {
            errorMsg.add(String.format("身份证号为%s的技术员不存在", salaryWay.getIdCard()));
            return new ExcelVerifyHandlerResult(false, errorMsg.toString());
        }
        Long employeeId = employee.getId();
        PayableSalary payableSalary = payableSalaryService.getByEmployeeIdAndMonths(employeeId, salaryWay.getMonths());
        if (Objects.isNull(payableSalary)) {
            errorMsg.add(String.format("技术员[%s]的没有找到应发薪资", employee.getName()));
            return new ExcelVerifyHandlerResult(false, errorMsg.toString());
        }
        Long payableSalaryId = payableSalary.getId();

        BigDecimal salary = salaryWay.getPayableSalary();
        fillingSalaryWay(salaryWay);
        BigDecimal wayTotal = BigDecimal.ZERO.add(salaryWay.getXinYue())
                .add(salaryWay.getBangMang())
                .add(salaryWay.getYiCai())
                .add(salaryWay.getCloudAccount())
                .add(salaryWay.getBeijingForeignService());
        if (!salary.equals(wayTotal)) {
            errorMsg.add(String.format("技术员[%s]工资发放途径总和不等于应发薪资", salaryWay.getEmployeeName()));
        }

        if (errorMsg.length() > 0) {
            return new ExcelVerifyHandlerResult(false, errorMsg.toString());
        }

        salaryWay.setEmployeeId(employeeId);
        salaryWay.setPayableSalaryId(payableSalaryId);
        salaryWay.setProjectId(employee.getProjectId());
        salaryWay.setEmployeeStatus(employee.getStatus());
        salaryWay.setOrgId(employee.getOrgId());
        salaryWay.setInternalCode(employee.getInternalCode());

        return new ExcelVerifyHandlerResult(true);
    }
}
导入导出工具类
package com.ztbase.system.util;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.ztbase.system.common.enums.ResultEnum;
import com.ztbase.system.exception.BizException;
import com.ztbase.system.handle.excel.BigDecimalHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description: 文件相关操作
 * @author: shunyuM
 * @create: 2019-09-10 11:19
 **/
@Slf4j
public class FileExportUtils {

    private static final String EXPORT_FILE_ERROR_MESSAGE = "导出文件出错,请稍后再试!";

    /**
     * 私有构造
     */
    private FileExportUtils() {
    }

    /**
     * 获取对象实例
     *
     * @return
     */
    public static FileExportUtils getInstance() {
        return new FileExportUtils();
    }

    /**
     * 导出文本为文件
     *
     * @param fileName    导出文件名称
     * @param fileContent 导出文件的内容
     * @param request     http请求对象
     * @param response    http响应对象
     */
    public void exportFile(String fileName, String fileContent, HttpServletRequest request, HttpServletResponse response) {
        try (OutputStream os = response.getOutputStream(); PrintStream ps = new PrintStream(os, true, "utf8")) {
            exportPrepare(fileName, request, response);
            ps.print(fileContent);
            ps.flush();
        } catch (IOException e) {
            log.error(EXPORT_FILE_ERROR_MESSAGE);
        }
    }

    /**
     * 直接导出response流中内容
     *
     * @param fileName 导出文件名称
     * @param request  http请求对象
     * @param response http响应对象
     */
    public void exportFile(String fileName, HttpServletRequest request, HttpServletResponse response) {
        try (OutputStream os = response.getOutputStream(); PrintStream ps = new PrintStream(os, true, "utf8")) {
            exportPrepare(fileName, request, response);
            ps.flush();
        } catch (IOException e) {
            log.error(EXPORT_FILE_ERROR_MESSAGE);
        }

    }

    /**
     * 导出文件, 使用对象反序列化处理
     *
     * @param fileName
     * @param object
     * @param request
     * @param response
     */
    public void exportFile(String fileName, Object object, HttpServletRequest request, HttpServletResponse response) {
        exportPrepare(fileName, request, response);
        try (OutputStream os = response.getOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(os)) {
            oos.writeObject(object);
        } catch (IOException e) {
            log.error(EXPORT_FILE_ERROR_MESSAGE);
        }
    }

    /**
     * 导出文件, 使用对象反序列化处理
     *
     * @param fileName 文件名
     * @param object   导出对象
     */
    public void exportFile(String fileName, Object object) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        Assert.isTrue(null != requestAttributes, "request attributes is required be non-blank");
        ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = attributes.getRequest();
        HttpServletResponse response = attributes.getResponse();
        exportFile(fileName, object, request, response);
    }

    /**
     * 导出文件前, 处理request和response的请求头, 使请求已文件形式被下载
     *
     * @param fileName
     * @param request
     * @param response
     */
    public void exportPrepare(String fileName, HttpServletRequest request, HttpServletResponse response) {
        String agent = request.getHeader("user-agent");
        String fireFox = "Firefox";
        try {
            if (agent.contains(fireFox)) {
                // 火狐浏览器
                Base64.Encoder encoder = Base64.getEncoder();
                fileName = "=?utf-8?B?" + encoder.encodeToString(fileName.getBytes("utf-8")) + "?=";
            } else {
                // 其它浏览器
                fileName = URLEncoder.encode(fileName, "utf-8");
            }
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("file-name", fileName);
            response.setContentType("application/vnd.ms-excel");
        } catch (Exception e) {
            log.error("set export env failed");
        }
    }

    public void exportExcel(String title, String sheetName, Class<?> pojoClass, Collection<?> dataSet, OutputStream os) {
        ExportParams exportParams = new ExportParams(title, sheetName);
        BigDecimalHandler bigDecimalHandler = new BigDecimalHandler();
        List<String> excelField = Arrays.stream(pojoClass.getDeclaredFields())
                .map(field -> field.getAnnotation(Excel.class))
                .filter(Objects::nonNull)
                .map(Excel::name)
                .collect(Collectors.toList());
        bigDecimalHandler.setNeedHandlerFields(excelField.toArray(new String[excelField.size()]));
        exportParams.setDataHandler(bigDecimalHandler);
        try (Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, dataSet)) {
            workbook.write(os);
        } catch (IOException e) {
            throw BizException.build(ResultEnum.IO_OPERATION_FAILED);
        }
    }

}

2.复杂的excel可以先建造一个模板

模板

模板

接收前端请求
	@GetMapping("/export")
    @ApiOperation(tags = "导出应发工资表", value = "导出应发工资表")
    public void exportExcel(PayableSalaryQuery payableSalaryQuery, HttpServletRequest request, HttpServletResponse response) {
        // 01 设置模板
        TemplateExportParams templateParams = new TemplateExportParams("templates/excel/salary_export_template_v1.0.xlsx", true);
        templateParams.setSheetName(new String[]{"应发工资表"});
        payableSalaryQuery.setCurrent(1L);
        payableSalaryQuery.setSize(999L);
        List<PayableSalaryDTO> payableSalaryDTOList = payableSalaryService.list(payableSalaryQuery).stream()
                .sorted(Comparator.comparing(PayableSalaryDTO::getProjectId).thenComparing(PayableSalaryDTO::getEmployeeId))
                .collect(toList());
        if (CollectionUtils.isEmpty(payableSalaryDTOList)) {
            return;
        }

        // 02 准备数据源,excel中的表达式即为map的key
        Map<String, Object> map = payableSalaryService.convertToExcelFormat(payableSalaryDTOList);
        
        // 03 导出
        FileExportUtils exportUtils = FileExportUtils.getInstance();
        exportUtils.exportPrepare("应发工资表.xlsx", request, response);
        try (Workbook workbook = ExcelExportUtil.exportExcel(templateParams, map)) {
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw BizException.build(ResultEnum.IO_OPERATION_FAILED);
        }
    }

附上官方文档地址:http://doc.wupaas.com/docs/easypoi

导出
FileExportUtils exportUtils = FileExportUtils.getInstance();
exportUtils.exportPrepare(“应发工资表.xlsx”, request, response);
try (Workbook workbook = ExcelExportUtil.exportExcel(templateParams, map)) {
workbook.write(response.getOutputStream());
} catch (IOException e) {
throw BizException.build(ResultEnum.IO_OPERATION_FAILED);
}
}


附上官方文档地址:http://doc.wupaas.com/docs/easypoi





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值