easypoi导入案例

news2024/11/17 13:48:49

文章目录

  • easypoi导入案例
    • 一、依赖
    • 二、导出模板
      • 1、excel模板实体类(同下)
      • 2、具体实现类
      • 3、easypoi工具类中的方法
      • 4、自定义样式类
    • 三、导入校验
      • 1、excel模板实体类
      • 2、具体实现类
      • 3、自定义信号导入校验类

easypoi导入案例

一、依赖

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

二、导出模板

1、excel模板实体类(同下)

在这里插入图片描述

2、具体实现类

    public void exportTemplate(HttpServletResponse response) {
        CodingUtils.checkUserIdBefore();

        List<SignalTemplateVO> list = new ArrayList<>();

        String title = "信号模板";
        String time = DateUtil.timeStamp2Date2(System.currentTimeMillis(), "yyyyMMddHHmmss");
        String fileName = "设备信号模板(" + time + ")";
        try {
            EasyPoiUtil.exportExcel2Signal(list, title, "设备信号", SignalTemplateVO.class,
                    fileName, true, true, true,response);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

3、easypoi工具类中的方法

这里设置下拉框,ExcelType必须为HSSF

ExportParams exportParams = new ExportParams(title, sheetName, ExcelType.HSSF);

package com.mye.cloudboxdcim.framework.engine.poi;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.afterturn.easypoi.excel.imports.ExcelImportService;
import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;
import com.mye.cloudboxdcim.framework.engine.poi.myeasypoi.ExcelExportTitleStyle;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

/**
 * @ClassName EasyPoiUtil
 * @Description easypoi 工具类
 * @Author hl
 * @Date 2022/11/6 12:27
 * @Version 1.0
 */
public class EasyPoiUtil {

    /**
     * excel 导出
     *
     * @param list           数据
     * @param title          标题
     * @param sheetName      sheet名称
     * @param pojoClass      pojo类型
     * @param fileName       文件名称
     * @param isCreateHeader 是否创建表头
     * @param isStyle        是否自定义表头样式
     * @param response 响应流
     */
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader,boolean isStyle, HttpServletResponse response) throws IOException {
        ExportParams exportParams = new ExportParams(title, sheetName, ExcelType.XSSF);
        exportParams.setCreateHeadRows(isCreateHeader);
        if (isStyle){
            exportParams.setStyle(ExcelExportTitleStyle.class);
        }
        defaultExport(list, pojoClass, fileName, response, exportParams);
    }

    /**
     * excel 导出闪断震荡规则模板
     *
     * @param list           数据
     * @param title          标题
     * @param sheetName      sheet名称
     * @param pojoClass      pojo类型
     * @param fileName       文件名称
     * @param isCreateHeader 是否创建表头
     * @param isStyle        是否自定义表头样式
     * @param isSelectList   是否自定义下拉框
     * @param response 响应流
     */
    public static void exportExcel2FlashShockRule(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader,boolean isStyle,boolean isSelectList, HttpServletResponse response) throws IOException {
        ExportParams exportParams = new ExportParams(title, sheetName, ExcelType.HSSF);
        exportParams.setCreateHeadRows(isCreateHeader);
        if (isStyle){
            exportParams.setStyle(ExcelExportTitleStyle.class);
        }
        if (isSelectList){
            Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
            //规则状态
            selectList(workbook,2,1000,4,4,new String[]{"启用","停用"});
            //告警级别
            selectList(workbook,2,1000,5,5,new String[]{"提示","次要","重要","紧急"});
            //闪断分析状态
            selectList(workbook,2,1000,7,7,new String[]{"启用","停用"});
            //闪断状态
            selectList(workbook,2,1000,9,9,new String[]{"丢弃","屏蔽"});
            //震荡状态
            selectList(workbook,2,1000,10,10,new String[]{"启用","停用"});
            //震荡处理策略
            selectList(workbook,2,1000,15,15,new String[]{"产生振荡告警并将触发振荡后的源告警显示在屏蔽告警中","产生振荡告警源告警直接上报","产生振荡告警并丢弃触发振荡后的源告警","重定义触发振荡后的源告警级别"});
            //源告警级别
            selectList(workbook,2,1000,16,16,new String[]{"提示","次要","重要","紧急"});
            //优先级
            selectList(workbook,2,1000,17,17,new String[]{"最高","高","中","低","最低"});

            downLoadExcel(fileName, response, workbook);
        }
        defaultExport(list, pojoClass, fileName, response, exportParams);
    }


    /**
     * excel 导出设备信号模板
     *
     * @param list           数据
     * @param title          标题
     * @param sheetName      sheet名称
     * @param pojoClass      pojo类型
     * @param fileName       文件名称
     * @param isCreateHeader 是否创建表头
     * @param isStyle        是否自定义表头样式
     * @param isSelectList   是否自定义下拉框
     * @param response 响应流
     */
    public static void exportExcel2Signal(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader,boolean isStyle,boolean isSelectList, HttpServletResponse response) throws IOException {
        ExportParams exportParams = new ExportParams(title, sheetName, ExcelType.HSSF);
        exportParams.setCreateHeadRows(isCreateHeader);
        if (isStyle){
            exportParams.setStyle(ExcelExportTitleStyle.class);
        }
        if (isSelectList){
            Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
            //信号属性类型
            selectList(workbook,2,1000,5,5,new String[]{"AI","DI","Other","DO"});
            //类型
            selectList(workbook,2,1000,10,10,new String[]{"采集信号","统计信号"});
            downLoadExcel(fileName, response, workbook);
        }
        defaultExport(list, pojoClass, fileName, response, exportParams);
    }

    /**
     * excel 导出
     *
     * @param list      数据
     * @param title     标题
     * @param sheetName sheet名称
     * @param pojoClass pojo类型
     * @param fileName  文件名称
     * @param response
     */
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response) throws IOException {
        defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName, ExcelType.XSSF));
    }

    /**
     * excel 导出
     *
     * @param list         数据
     * @param pojoClass    pojo类型
     * @param fileName     文件名称
     * @param response
     * @param exportParams 导出参数
     */
    public static void exportExcel(List<?> list, Class<?> pojoClass, String fileName, ExportParams exportParams, HttpServletResponse response) throws IOException {
        defaultExport(list, pojoClass, fileName, response, exportParams);
    }

    /**
     * excel 导出
     *
     * @param list     数据
     * @param fileName 文件名称
     * @param response
     */
    public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response) throws IOException {
        defaultExport(list, fileName, response);
    }

    /**
     * 默认的 excel 导出
     *
     * @param list         数据
     * @param pojoClass    pojo类型
     * @param fileName     文件名称
     * @param response
     * @param exportParams 导出参数
     */
    private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) throws IOException {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        downLoadExcel(fileName, response, workbook);
    }

    /**
     * 默认的 excel 导出
     *
     * @param list     数据
     * @param fileName 文件名称
     * @param response
     */
    private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) throws IOException {
        Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
        downLoadExcel(fileName, response, workbook);
    }

    /**
     * 下载
     *
     * @param fileName 文件名称
     * @param response
     * @param workbook excel数据
     */
    private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) throws IOException {
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + "." + EasyPoiUtil.ExcelTypeEnum.XLSX.getValue(), "UTF-8"));
            workbook.write(response.getOutputStream());
        } catch (Exception e) {
            throw new IOException(e.getMessage());
        }
    }

   /**
      * @MethodName selectList
      * @Description  生成下拉列表
      * @param workbook
      * @param firstRow 下拉单元格行号 从0开始
      * @param lastRow 下拉单元格结束行号
      * @param firstCol 下拉单元格列号 从0开始
      * @param lastCol  下拉单元格结束列号
      * @param dataList 动态生成的下拉内容
      * @Author hl
      * @Date 2022/11/22 14:21
      */
    public static void selectList(Workbook workbook,int firstRow,int lastRow,int firstCol,int lastCol,String[] dataList ){
        Sheet sheet = workbook.getSheetAt(0);

        //生成下拉列表
        CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
        //生成下拉框内容
        DVConstraint dvConstraint  = DVConstraint.createExplicitListConstraint(dataList);
        HSSFDataValidation dataValidation  = new HSSFDataValidation(cellRangeAddressList, dvConstraint);

        //设置错误信息提示
        dataValidation.setShowErrorBox(true);
        //对sheet页生效
        sheet.addValidationData(dataValidation );
    }

    /**
     * excel 导入
     *
     * @param filePath   excel文件路径
     * @param titleRows  标题行
     * @param headerRows 表头行
     * @param pojoClass  pojo类型
     * @param <T>
     * @return
     */
    public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
        if (StringUtils.isBlank(filePath)) {
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        params.setNeedSave(true);
        params.setSaveUrl("/excel/");
        try {
            return ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
        } catch (NoSuchElementException e) {
            throw new IOException("模板不能为空");
        } catch (Exception e) {
            throw new IOException(e.getMessage());
        }
    }

    /**
     * excel 导入
     *
     * @param file      excel文件
     * @param pojoClass pojo类型
     * @param <T>
     * @return
     */
    public static <T> List<T> importExcel(MultipartFile file, Class<T> pojoClass) throws IOException {
        return importExcel(file, 1, 1, pojoClass);
    }

    /**
     * excel 导入
     *
     * @param file       excel文件
     * @param titleRows  标题行
     * @param headerRows 表头行
     * @param pojoClass  pojo类型
     * @param <T>
     * @return
     */
    public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws IOException {
        return importExcel(file, titleRows, headerRows, false, pojoClass);
    }


    public static <T>  ExcelImportResult<?> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass,
                                          Integer sheetIndex, boolean isVerify, IExcelVerifyHandler handler) throws IOException {
        try {
            ImportParams importParams = new ImportParams();
            importParams.setTitleRows(1); // 设置标题列占几行
            importParams.setHeadRows(2);  // 设置字段名称占几行 即header
            importParams.setNeedVerify(true);//开启校验
            importParams.setVerifyHandler(handler);// MyVerifyHandler这个类是自己创建的
            importParams.setStartSheetIndex(0);  // 设置从第几张表格开始读取,这里0代表第一张表,默认从第一张表读取
            return new ExcelImportService().importExcelByIs(file.getInputStream(), pojoClass, importParams, true);
        } catch (Exception e) {
            throw new IOException(e.getMessage());
        }
    }


    public static <T> ExcelImportResult importExcelResult(MultipartFile file, Class<T> pojoClass) throws IOException {

        try {
            ImportParams importParams = new ImportParams();
            importParams.setTitleRows(1); // 设置标题列占几行
            importParams.setHeadRows(2);  // 设置字段名称占几行 即header
            importParams.setNeedVerify(true);//开启校验
//            importParams.setVerifyHandler(new MyVerifyHandler());// MyVerifyHandler这个类是自己创建的
            importParams.setStartSheetIndex(0);  // 设置从第几张表格开始读取,这里0代表第一张表,默认从第一张表读取
            return new ExcelImportService().importExcelByIs(file.getInputStream(), pojoClass, importParams, true);
        } catch (Exception e) {
            throw new IOException(e.getMessage());
        }
    }

    /**
     * excel 导入
     *
     * @param file       上传的文件
     * @param titleRows  标题行
     * @param headerRows 表头行
     * @param needVerfiy 是否检验excel内容
     * @param pojoClass  pojo类型
     * @param <T>
     * @return
     */
    public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, boolean needVerfiy, Class<T> pojoClass) throws IOException {
        if (file == null) {
            return null;
        }
        try {
            return importExcel(file.getInputStream(), titleRows, headerRows, needVerfiy, pojoClass);
        } catch (Exception e) {
            throw new IOException(e.getMessage());
        }
    }

    /**
     * excel 导入
     *
     * @param inputStream 文件输入流
     * @param titleRows   标题行
     * @param headerRows  表头行
     * @param needVerfiy  是否检验excel内容
     * @param pojoClass   pojo类型
     * @param <T>
     * @return
     */
    public static <T> List<T> importExcel(InputStream inputStream, Integer titleRows, Integer headerRows, boolean needVerfiy, Class<T> pojoClass) throws IOException {
        if (inputStream == null) {
            return null;
        }

        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        params.setSaveUrl("/excel/");
        params.setNeedSave(true);
        params.setNeedVerify(needVerfiy);
        try {
            return ExcelImportUtil.importExcel(inputStream, pojoClass, params);
        } catch (NoSuchElementException e) {
            throw new IOException("excel文件不能为空");
        } catch (Exception e) {
            throw new IOException(e.getMessage());
        }
    }

    /**
     * Excel 类型枚举
     */
    enum ExcelTypeEnum {
        /**
         * 文件类型
         */
        XLS("xls"), XLSX("xlsx");
        private String value;

        ExcelTypeEnum(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }
}

4、自定义样式类

package com.mye.cloudboxdcim.framework.engine.poi.myeasypoi;

import cn.afterturn.easypoi.excel.export.styler.AbstractExcelExportStyler;
import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler;
import cn.hutool.core.util.ObjectUtil;
import org.apache.poi.ss.usermodel.*;

/**
 * @ClassName EasyPoiUtil
 * @Description 导出自定义title的工具类
 * @Author hl
 * @Date 2022/11/6 12:27
 * @Version 1.0
 */
public class ExcelExportTitleStyle extends AbstractExcelExportStyler implements IExcelExportStyler {

    public ExcelExportTitleStyle(Workbook workbook) {
        super.createStyles(workbook);
    }

    @Override
    public CellStyle getTitleStyle(short color) {
        CellStyle titleStyle = workbook.createCellStyle();
        // 自定义字体
        Font font = workbook.createFont();
        font.setColor(IndexedColors.WHITE1.getIndex());
        font.setBold(true);
        font.setFontName("宋体");
        titleStyle.setFont(font);

		// 自定义背景色
        titleStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
        titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

        titleStyle.setBorderBottom(BorderStyle.THIN);
        titleStyle.setBorderTop(BorderStyle.THIN);
        titleStyle.setBorderLeft(BorderStyle.THIN);
        titleStyle.setBorderRight(BorderStyle.THIN);

        titleStyle.setAlignment(HorizontalAlignment.CENTER);
        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        titleStyle.setWrapText(true);
        return titleStyle;
    }

    @Override
    public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) {
        CellStyle style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.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(HorizontalAlignment.CENTER);
        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        return titleStyle;
    }

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

}

三、导入校验

1、excel模板实体类

这个模板实体类,也就是导入的时候excel的样式,例如表头字段需要一样,也是导入校验的实体类,需要实现 IExcelDataModel, IExcelModel 重写 equals和hashCode方法和rowNum、errorMsg的get\set方法

package com.mye.cloudboxdcim.framework.api.vo.device;

import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelTarget;
import cn.afterturn.easypoi.handler.inter.IExcelDataModel;
import cn.afterturn.easypoi.handler.inter.IExcelModel;
import com.mye.cloudboxdcim.framework.engine.validator.anno.ContainsDataValid;
import com.mye.cloudboxdcim.framework.engine.validator.anno.HaveNoBlankValid;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.*;
import java.util.Objects;

/**
 * @ClassName SignalTemplateVO
 * @Description 信号模板出参
 * @Author hl
 * @Date 2022/11/6 14:06
 * @Version 1.0
 */
@Data
@ExcelTarget("SignalTemplateVO")
public class SignalTemplateVO implements IExcelDataModel, IExcelModel {

    /**
     * 行号
     */
    private int rowNum;

    /**
     * 错误消息
     */
    private String errorMsg;

    /**
     * 设备型号名称
     */
    @Excel(name = "设备型号名称(必填)",width = 20,orderNum = "0",isImportField = "true")
    @NotBlank(message = "设备型号名称不可以为空")
    @Length(min = 1, max = 32, message = "设备型号名称长度需要在32个字以内")
    private String deviceModelName;
    /**
     * 信号名称
     */
    @Excel(name = "信号名称(必填)",width = 20,orderNum = "1",isImportField = "true")
    @NotBlank(message = "信号名称不可以为空")
    @Pattern(regexp = "^[\\u4e00-\\u9fa5\\ A-Za-z0-9\\-\\_]{2,50}",message = "信号名称只能包含汉字,字母,数字,下划线,中横线,长度是2~50")
    private String name;

    /**
     * 描述
     */
    @Excel(name = "描述",width = 20,orderNum = "2",isImportField = "true")
    @HaveNoBlankValid(message = "描述长度最大为200",value = "description") //这个是自定义注解 集成hibernate-validator实现
    private String description;

    /**
     * 指标名称
     */
    @Excel(name = "指标名称(必填)",width = 20,orderNum = "3",isImportField = "true")
    @NotBlank(message = "指标名称不可以为空")
    @Pattern(regexp = "[a-zA-Z_:][a-zA-Z0-9_:]{2,200}",message = "指标名称只能包含字母、数字和下划线且以字母开头,长度是3~200")
    private String metricName;

    /**
     * 信号组名称
     */
    @Excel(name = "信号组名称(必填)",width = 20,orderNum = "4",isImportField = "true")
    @NotBlank(message = "信号分组名称不可以为空")
    @Pattern(regexp = "^[\\u4e00-\\u9fa5\\ A-Za-z0-9\\-\\_]{2,50}",message = "信号分组名称只能包含汉字,字母,数字,下划线,中横线,长度是2~50")
    private String signalGroup;

    /**
     * 信号属性(AI,DI,Other,DO)
     */
    @Excel(name = "信号属性类型(必填)",width = 20,orderNum = "5",isImportField = "true")
    @NotBlank(message = "信号属性不可以为空")
    @ContainsDataValid(message = "信号属性不正确",values = {"AI","DI","Other","DO"}) //这个是自定义注解 集成hibernate-validator实现
    private String propertyType;

    /**
     * 枚举量(DI时才有)
     */
    @Excel(name = "枚举量",width = 20,orderNum = "6",isImportField = "true")
    @HaveNoBlankValid(message = "枚举量格式不合法,例子(1:a)",value = "enumConstant") //这个是自定义注解 集成hibernate-validator实现
    private String enumConstant;

    /**
     * 精度
     */
    @Excel(name = "精度(必填)",width = 20,orderNum = "7",type = 10,isImportField = "true")
    @NotNull(message = "精度不能为空")
    @Min(value = 0,message = "精度最小值为0")
    @Max(value = 4,message = "精度最大值为4")
    private Integer precisions;

    /**
     * 单位
     */
    @Excel(name = "单位",width = 20,orderNum = "8",isImportField = "true")
    @HaveNoBlankValid(message = "单位长度最大为10",value = "unit") //这个是自定义注解 集成hibernate-validator实现
    private String unit;

    /**
     * 点索引
     */
    @Excel(name = "点索引(必填)",width = 20,orderNum = "9",type = 10,isImportField = "true")
    @NotNull(message = "点索引不能为空")
    @Min(value = 1,message = "点索引最小值为1")
    @Max(value = 9999,message = "点索引最大值为9999")
    private Integer pointIndex;

    /**
     * 类型(采集信号,统计信号)
     */
    @Excel(name = "类型(必填)",width = 20,orderNum = "10",isImportField = "true")
    @NotBlank(message = "信号类型不可以为空")
    @ContainsDataValid(message = "信号类型不正确",values = {"采集信号","统计信号"}) //这个是自定义注解 集成hibernate-validator实现
    private String type;


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()){
            return false;
        }
        SignalTemplateVO that = (SignalTemplateVO) o;
        return Objects.equals(name, that.name) && Objects.equals(deviceModelName, that.deviceModelName)
                && Objects.equals(metricName,that.metricName)&&Objects.equals(pointIndex,that.pointIndex);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, deviceModelName,metricName,pointIndex);
    }
    @Override
    public String getErrorMsg() {
        return errorMsg;
    }

    @Override
    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    @Override
    public int getRowNum() {
        return rowNum;
    }

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

2、具体实现类

public HttpResponseTemp<?> importByDeviceModelId(MultipartFile file,HttpServletResponse response) {
        checkFileType(file);

        ExcelImportResult<SignalTemplateVO> result;
        try {
            result = getDataByFile(file);
        }catch (Exception e){
            throw ApiException.wrapMessage(ResultStat.PARAM_ERROR,"Excel 读取失败,请检查模板");
        }
    
        List<SignalErrorVO> errorVOList = getFailData(result);
        if (CollUtil.isNotEmpty(errorVOList)){
            String time = DateUtil.timeStamp2Date2(System.currentTimeMillis(), "yyyyMMddHHmmss");
            String fileName = "信号导入错误信息(" + time + ")";
            try {
                EasyPoiUtil.exportExcel(errorVOList, "信号导入错误信息", "错误信息", SignalErrorVO.class, fileName, true, true, response);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return ResultStat.PARAM_ERROR.wrap("","导入模板中数据错误");
        }else {
            //成功数据
            handleSuccessData(result);
            return ResultStat.OK.wrap("", "导入数据成功");
        }
    }

    private List<SignalErrorVO> getFailData(ExcelImportResult<SignalTemplateVO> result) {
        List<SignalErrorVO> errorVOList = new ArrayList<>();
        if (ObjectUtil.isNotNull(result)){
            List<SignalTemplateVO> failList = result.getFailList();
            if (CollUtil.isNotEmpty(failList)) {
                failList.stream().filter(Objects::nonNull).forEach(s -> {
                    int line = s.getRowNum() + 1;
                    String msg = "第" + line + "行的错误是:" + s.getErrorMsg();
                    SignalErrorVO signalErrorVO = new SignalErrorVO();
                    signalErrorVO.setLine("第" + line + "行");
                    signalErrorVO.setMsg(msg);
                    errorVOList.add(signalErrorVO);
                });
            }
        }
        return errorVOList;
    }

    private ExcelImportResult<SignalTemplateVO> getDataByFile(MultipartFile file) {
        ExcelImportResult<SignalTemplateVO> result;
        SignalImportVerifyHandler signalImportVerifyHandler = new SignalImportVerifyHandler(deviceSignalMapper,deviceModelMapper);
        try {
            ImportParams importParams = new ImportParams();
            importParams.setTitleRows(1); // 设置标题列占几行
            importParams.setHeadRows(1);  // 设置字段名称占几行 即header
            importParams.setNeedVerify(true);//开启校验
            importParams.setVerifyHandler(signalImportVerifyHandler);// SignalImportVerifyHandler这个类是自己创建的
            importParams.setStartSheetIndex(0);  // 设置从第几张表格开始读取,这里0代表第一张表,默认从第一张表读取
            ExcelImportService excelImportService = new ExcelImportService();
            result = excelImportService.importExcelByIs(file.getInputStream(), SignalTemplateVO.class, importParams, true);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // 清除threadLocal 防止内存泄漏
            ThreadLocal<List<SignalTemplateVO>> threadLocal = signalImportVerifyHandler.getThreadLocal();
            if (threadLocal != null) {
                threadLocal.remove();
            }
        }
        return result;
    }

    private void checkFileType(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        if (StrUtil.isNotBlank(fileName)) {
            if (!fileName.endsWith("xls") && !fileName.endsWith("xlsx")) {
                throw ApiException.wrapMessage(ResultStat.PARAM_ERROR, "文件格式不对,请上传excel格式文件");
            }
        }
    }

3、自定义信号导入校验类

package com.mye.cloudboxdcim.framework.engine.poi.myeasypoi;

import cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHandlerResult;
import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mye.cloudboxdcim.framework.api.mapper.device.DeviceModelMapper;
import com.mye.cloudboxdcim.framework.api.mapper.device.DeviceSignalMapper;
import com.mye.cloudboxdcim.framework.api.pojo.devicemodel.DeviceModel;
import com.mye.cloudboxdcim.framework.api.pojo.devicesignal.DeviceSignal;
import com.mye.cloudboxdcim.framework.api.vo.device.SignalTemplateVO;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;

/**
 * 自定义信号导入校验类
 */
@Component
public class SignalImportVerifyHandler implements IExcelVerifyHandler<SignalTemplateVO> {

    private final ThreadLocal<List<SignalTemplateVO>> threadLocal = new ThreadLocal<>();


    private final DeviceSignalMapper deviceSignalMapper;

    private final DeviceModelMapper deviceModelMapper;

    public SignalImportVerifyHandler(DeviceSignalMapper deviceSignalMapper,DeviceModelMapper deviceModelMapper){
        this.deviceModelMapper = deviceModelMapper;
        this.deviceSignalMapper = deviceSignalMapper;
    }



    @Override
    public ExcelVerifyHandlerResult verifyHandler(SignalTemplateVO inputEntity) {

        StringJoiner joiner = new StringJoiner(",");
        //根据名称查看数据库中是否存在
        String name = inputEntity.getName();
        if (checkName(name)) {
            joiner.add("信号名称已经存在:" + name);
        }
        //检查设备型号是否存在
        DeviceModel deviceModel = checkModelName(inputEntity.getDeviceModelName());
        if (ObjectUtil.isNull(deviceModel)){
            joiner.add("设备型号不存在:" + inputEntity.getDeviceModelName());
        } else {
            //检查索引值
            Integer deviceModelId = deviceModel.getId();
            Integer pointIndex = inputEntity.getPointIndex();
            if (checkPointIndex(pointIndex,deviceModelId)){
                joiner.add(deviceModel.getName() + "对应的索引值(" + pointIndex + ")已经存在");
            }
        }

        List<SignalTemplateVO> threadLocalVal = threadLocal.get();
        if (CollUtil.isEmpty(threadLocalVal)){
            threadLocalVal = new ArrayList<>();
        }

        threadLocalVal.forEach(e -> {
            if (e.equals(inputEntity)) {
                int lineNumber = e.getRowNum() + 1;
                joiner.add("数据与第" + lineNumber + "行重复");
            }
        });
        // 添加本行数据对象到ThreadLocal中
        threadLocalVal.add(inputEntity);
        threadLocal.set(threadLocalVal);

        if (joiner.length() != 0) {
            return new ExcelVerifyHandlerResult(false, joiner.toString());
        }
        return new ExcelVerifyHandlerResult(true);
    }

    private Boolean checkPointIndex(Integer pointIndex,Integer deviceModelId) {
        LambdaQueryWrapper<DeviceSignal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeviceSignal::getDeviceModelId,deviceModelId).eq(DeviceSignal::getPointIndex,pointIndex);

        DeviceSignal deviceSignal = deviceSignalMapper.selectOne(queryWrapper);
        return ObjectUtil.isNotNull(deviceSignal);

    }

    private Boolean checkName(String name) {
        LambdaQueryWrapper<DeviceSignal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeviceSignal::getName,name);

        DeviceSignal deviceSignal = deviceSignalMapper.selectOne(queryWrapper);
        return ObjectUtil.isNotNull(deviceSignal);
    }

    private DeviceModel checkModelName(String name) {
        LambdaQueryWrapper<DeviceModel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeviceModel::getName,name);

        return deviceModelMapper.selectOne(queryWrapper);
    }

    public ThreadLocal<List<SignalTemplateVO>> getThreadLocal() {
        return threadLocal;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/63510.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第7 部分 HDLC 和PPP

路由器经常用于构建广域网&#xff0c;广域网链路的封装和以太网上的封装有着非常大的差别。常见的广域网封装有HDLC&#xff0c;PPP 和Frame-relay 等&#xff0c;本次介绍HDLC 和PPP。相对而言&#xff0c;PPP 比HDLC 有较多的功能。 7.1 HDLC 和PPP 简介 7.1.1 HDLC 介绍 H…

批处理及有状态等应用类型在 K8S 上应该如何配置?

众所周知, Kubernetes(K8S)更适合运行无状态应用, 但是除了无状态应用. 我们还会有很多其他应用类型, 如: 有状态应用, 批处理, 监控代理(每台主机上都得跑), 更复杂的应用(如:hadoop 生态...). 那么这些应用可以在 K8S 上运行么? 如何配置? 其实, K8S 针对这些都有对应的不…

操作系统:存储器管理 练习题(带有详细答案解析)

文章目录1.存储器的层次结构2.程序的装入和链接2.1.程序的装入2.2.程序的链接3.连续分配存储管理方式3.1.单一连续分配3.2.固定分区分配3.3.动态分区分配3.4.基于顺序搜索的动态分区分配算法3.5.基于索引搜索的动态分区分配算法3.6.动态可重定位分区分配4.对换4.1.多道程序环境…

SBT 树原理和实战

一 基本概念 SBT&#xff08;Size Balanced Tree&#xff0c;节点大小平衡树&#xff09;是一种自平衡二叉查找树&#xff0c;通过子树的大小来保持平衡。与红黑树、AVL 树等自平衡二叉查找树相比&#xff0c;SBT更易于实现。SBT 可以在 O (logn) 时间内完成所有二叉搜索树的相…

【考研】操作系统复习冲刺(2023年408)

前言 本文内容主要源自于王道讲解的学习笔记总结。梳理《操作系统》考点&#xff08;以理论为重点&#xff09;&#xff0c;并对重点内容划下横线和加粗标注&#xff0c;方便考研复习。 可搭配以下链接一起学习&#xff1a; 【考研复习】《操作系统原理》孟庆昌等编著课后习…

数字IC手撕代码-同步FIFO

前言&#xff1a; 本专栏旨在记录高频笔面试手撕代码题&#xff0c;以备数字前端秋招&#xff0c;本专栏所有文章提供原理分析、代码及波形&#xff0c;所有代码均经过本人验证。 目录如下&#xff1a; 1.数字IC手撕代码-分频器&#xff08;任意偶数分频&#xff09; 2.数字…

磁环选型攻略及EMC整改技巧

磁环选型攻略及EMC整改技巧 今天跟大家分享一下磁环选型及应用相关的知识&#xff0c;希望对你有帮助。 本文将从以下四个方面对磁环进行阐述。 一、磁环的应用场景 首先我们来看几张图片 图1 显示屏VGA线 图2 适配器连接线 图3 USB通信线 这三根线都是我们生活中常见的供电…

简单个人网页设计作业 静态HTML个人博客主页——HTML+CSS+JavaScript 明星鹿晗(7页)

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

ping回显间隔长或第一个包很久才显示是怎么回事?

问题现象 在ping某些域名的时候&#xff0c;第一个回显十几秒才出现&#xff0c;但时延time正常&#xff0c;第二个包开始回显频率正常且最终统计结果为不丢包&#xff1b;或是每一个回显均间隔数秒才显示&#xff0c;但时延time又都是正常的&#xff0c;且统计结果为不丢包。…

U-Net 模型改进和应用场景研究性综述

U-Net综述1 文章介绍2 U-Net介绍3 结构改进4 非结构改进4.1 预处理——数据增强4.2 训练——数据归一化4.3 训练——激活函数4.4 训练——损失函数4.5 结构改进总结5 U-Net应用场景5.1 视网膜血管分割5.2 肺结节分割5.3 肝脏和肝脏肿瘤分割5.4 脑肿瘤分割5.5 不同应用场景总结6…

[附源码]计算机毕业设计基于Springboot校刊投稿系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Vue学习:模板语法

容器里面的模板&#xff1a;对应的模板语法 {{xxx}}:插值语法 指令语法&#xff1a; v-bind&#xff1a;vue指令 绑定 后面的数据会变成属性或者方法 <h1>指令语法</h1><!-- v-bind会将"xxx"里面的内容当成表达式执行 --><a v-bind:href&quo…

这些 MySQL 最朴素的监控方式!用完爱不释手!

对于当前数据库的监控方式有很多&#xff0c;分为数据库自带、商用、开源三大类&#xff0c;每一种都有各自的特色&#xff1b;而对于 mysql 数据库由于其有很高的社区活跃度&#xff0c;监控方式更是多种多样&#xff0c;不管哪种监控方式最核心的就是监控数据&#xff0c;获取…

嵌入式之总线协议:1、UART

嵌入式之总线协议&#xff1a;1、UART 目录 第一章 UART 帧格式讲解 第二章 UART 寄存器讲解 第三章 UART 编程 第四章 输出重定向 第五章 RS232、RS485协议原理与应用 第一章 UART嵌入式之总线协议&#xff1a;1、UART前言一、UART简介1、串行/并行1.1 并行1.2 串行2、异步3、…

C语言第十八课:初阶结构体

目录 前言&#xff1a; 一、结构体类型的声明&#xff1a; 1.结构的基础知识&#xff1a; 2.结构的声明&#xff1a; 3.结构成员允许的类型&#xff1a; 4.结构体变量的定义&#xff1a; 5.结构体变量的初始化&#xff1a; 二、结构体成员的访问&#xff1a; 1.结构体变量访…

[附源码]计算机毕业设计实验室管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

4 第一个程序

第一个程序 1 源程序 源程序中包括两种指令&#xff1a;伪指令和汇编指令 汇编指令是有对应机器码的指令&#xff0c;可以用CPU直接执行 伪指令没有对应的机器码&#xff0c;只有编译器执行不用CPU执行 1.1 segment ends segment和ends的功能是定义一个段。使用格式如下 …

[附源码]计算机毕业设计三星小区车辆登记系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

多线程中的公平锁、非公平锁、可重入锁、死锁【详细总结】

目录公平锁非公平锁公平锁和非公平锁的用法可重入锁synchronized可重入锁示例ReentrantLock的示例代码死锁死锁产生的原因常用解决死锁的方法判断程序是否发生死锁死锁的案例&#xff08;面试会问&#xff09;公平锁 多个线程按照申请锁的顺序去获得锁&#xff0c;线程会直接进…

第十六章 Dijkstra算法的讲解以及证明(与众不同的通俗证明)

第十六章 Dijsktra算法的讲解以及粗略证明一、Dijkstra的用途二、Dijkstra的思想及证明&#xff08;1&#xff09;相关结论及证明&#xff1a;结论1&#xff1a;必须借助中间点时某个点到终点的最短路程&#xff1d;该点到中间点的最短距离&#xff0b;中间点到终点的最短距离结…