最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Java實(shí)現(xiàn)Excel導(dǎo)入并進(jìn)行數(shù)據(jù)校驗(yàn)

 更新時(shí)間:2025年03月04日 09:59:14   作者:Javaの甘乃迪  
這篇文章主要為大家詳細(xì)介紹了Java如何根據(jù)下載的指定數(shù)據(jù)模板寫入數(shù)據(jù)和導(dǎo)入并進(jìn)行數(shù)據(jù)校驗(yàn),文中的示例代碼講解詳細(xì),需要的可以了解下

一、產(chǎn)品需求

1.下載指定的excel數(shù)據(jù)模板

2.excel模板寫入數(shù)據(jù)并導(dǎo)入

3.導(dǎo)入的時(shí)候根據(jù)校驗(yàn)規(guī)則進(jìn)行篩選,導(dǎo)入成功的返回成功列表,數(shù)據(jù)存在問題的返回失敗列表,失敗列表支持?jǐn)?shù)據(jù)編輯修正

看到需求的第一眼,可能就覺得第三點(diǎn)有點(diǎn)難度,我們知道,傳統(tǒng)的數(shù)據(jù)校驗(yàn)可以通過在傳輸對(duì)象dto上面加注解實(shí)現(xiàn)。

//第一種
public Result test1(@RequestBody @Validated TestDTO dto) {...}
 
//第二種
public Result test2(@RequestBody @Valid TestDTO dto{...}
//第三種
public Result test3(@RequestBody @Validated(value = {SaveGroup.class}) TestDTO dto) {...}
 

TestDTO里面會(huì)有一些類似 @NotNull、@NotBlank@Size等校驗(yàn)注解,這里就不列了。

然后在全局異常攔截那里進(jìn)行統(tǒng)一封裝,使其返回的數(shù)據(jù)結(jié)構(gòu)盡量保持統(tǒng)一,所以一般還得有一個(gè)RestExceptionHandler類。

@ControllerAdvice
public class RestExceptionHandler {
 
    /**
     * 處理參數(shù)驗(yàn)證失敗異常
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    private Response<?> methodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.warn("MethodArgumentNotValidException", e);
        FieldError fieldError = e.getBindingResult().getFieldError();
        return ResponseUtils.create(CommonCodeEnum.VALIDATE_ERROR.getCode(), CommonCodeEnum.VALIDATE_ERROR.getMessage(), fieldError.getDefaultMessage());
    }
}

講到常見的數(shù)據(jù)校驗(yàn),那么我們畫風(fēng)一轉(zhuǎn),再回來看需求,可見以上是不滿足需求的,首先,我們的入?yún)⑹且粋€(gè)文件流(指定的Excel模板文件),我們得先解析文件再進(jìn)行數(shù)據(jù)校驗(yàn),合法的放一個(gè)集合,不合法的放另一個(gè)集合;再者,即使入?yún)⑹且粋€(gè)數(shù)組,這種校驗(yàn)一旦不滿足立馬進(jìn)異常處理了,無法返回給前端正確的數(shù)據(jù)結(jié)構(gòu),所以今天就分享解決這類需求的解決方案。 

二、解決方法

基礎(chǔ)數(shù)據(jù)

UserExcelVO

import lombok.Data;
 
import java.util.List;
 
/**
 *
 */
@Data
public class UserExcelVO {
 
    /**
     * 成功列表
     */
    private List<UserExcel> success;
 
    /**
     * 失敗列表
     */
    private List<UserExcel> fail;
}

UserExcel

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.io.Serializable;
 
/**
 *
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserExcel implements Serializable {
 
    @NotBlank(message = "手機(jī)號(hào)不能為空")
    @Size(max = 4)
    @ExcelProperty(value = "用戶名", index = 0)
    private String name;
 
    @ExcelProperty(value = "年齡", index = 1)
    private Integer age;
 
    @Pattern(regexp = "^[1][3,4,5,7,8][0-9]{9}$$", message = "手機(jī)號(hào)不合法")
    @NotBlank(message = "手機(jī)號(hào)不能為空")
    @ExcelProperty(value = "手機(jī)號(hào)", index = 2)
    private String mobile;
 
    @ExcelProperty(value = "性別", index = 3)
    private String sex;
 
}

excel模板數(shù)據(jù)

方案一:大量if-else判斷校驗(yàn)

import com.alibaba.excel.EasyExcel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
 
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
/**
 *
 */
@RestController
@RequestMapping("/excel")
public class ExcelController {
 
    @PostMapping("/importExcel1")
    public UserExcelVO importExcel(@RequestParam("file") MultipartFile file) {
        List<UserExcel> list;
        List<UserExcel> fail = new ArrayList<>();
        UserExcelVO userExcelVO = new UserExcelVO();
        String mobileReg = "^[1][3,4,5,7,8][0-9]{9}$";
        try {
            list = EasyExcel.read(file.getInputStream(), UserExcel.class, new ModelExcelListener()).sheet().doReadSync();
 
            list.forEach(data -> {
                // 處理姓名的校驗(yàn)
                if (StringUtils.isEmpty(data.getName()) || data.getName().length() > 4) {
                    fail.add(data);
                    return;
                }
                // 處理手機(jī)號(hào)的校驗(yàn)
                if (StringUtils.isEmpty(data.getMobile()) || !data.getMobile().matches(mobileReg)) {
                    fail.add(data);
                    return;
                }
                // 以下根據(jù)字段多少可能有n個(gè)if...
 
            });
            userExcelVO.setFail(fail);
            list.removeAll(fail);
            userExcelVO.setSuccess(list);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return userExcelVO;
    }
 
}

方案二:請(qǐng)求體加入注解進(jìn)行校驗(yàn)

實(shí)際的業(yè)務(wù)場景,一個(gè)excel里面假如是訂單數(shù)據(jù),最少是幾十個(gè)字段起步的,難道要寫幾十個(gè)if else嗎?方案一明顯是不合理的,因此使用注解的方式幫我們解決。

ValidationUtils

import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
 
/**
 *
 */
public class ValidationUtils {
 
    public static Validator getValidator() {
        return validator;
    }
 
    static Validator validator;
 
    static {
        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
        validator = validatorFactory.getValidator();
    }
 
}

ModelExcelListener

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 *
 */
@Slf4j
public class ModelExcelListener extends AnalysisEventListener<UserExcel> {
 
    private List<UserExcel> datas = new ArrayList<>();
 
    /**
     * 通過 AnalysisContext 對(duì)象還可以獲取當(dāng)前 sheet,當(dāng)前行等數(shù)據(jù)
     */
    @Override
    public void invoke(UserExcel data, AnalysisContext context) {
        //數(shù)據(jù)存儲(chǔ)到list,供批量處理,或后續(xù)自己業(yè)務(wù)邏輯處理。
        log.info("讀取到數(shù)據(jù){}",data);
        datas.add(data);
        //根據(jù)業(yè)務(wù)自行處理,可以寫入數(shù)據(jù)庫等等
 
    }
 
    //所有的數(shù)據(jù)解析完了調(diào)用
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("所有數(shù)據(jù)解析完成");
    }
 
}

請(qǐng)求

import com.alibaba.excel.EasyExcel;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
 
import javax.validation.ConstraintViolation;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
 
/**
 *
 */
@RestController
@RequestMapping("/excel")
public class ExcelController {
 
    @PostMapping("/importExcel2")
    public UserExcelVO importExcelV2(@RequestParam("file") MultipartFile file) {
        List<UserExcel> list;
        List<UserExcel> fail = new ArrayList<>();
        UserExcelVO userExcelVO = new UserExcelVO();
        try {
            list = EasyExcel.read(file.getInputStream(), UserExcel.class, new ModelExcelListener()).sheet().doReadSync();
            list.forEach(data -> {
                Set<ConstraintViolation<UserExcel>> violations = ValidationUtils.getValidator().validate(data);
                if (violations.size() > 0) {
                    fail.add(data);
                }
            });
            userExcelVO.setFail(fail);
            list.removeAll(fail);
            userExcelVO.setSuccess(list);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return userExcelVO;
    }
 
}

三、測試結(jié)果

方案一的結(jié)果:

{
    "success": [
        {
            "name": "張2",
            "age": 19,
            "mobile": "13056781235",
            "sex": "女"
        },
        {
            "name": "張3",
            "age": 20,
            "mobile": "13056781236",
            "sex": "男"
        },
        {
            "name": "張4",
            "age": 21,
            "mobile": "13056781237",
            "sex": "女"
        },
        {
            "name": "張5",
            "age": 22,
            "mobile": "13056781238",
            "sex": "男"
        },
        {
            "name": "張6",
            "age": 23,
            "mobile": "13056781239",
            "sex": "男"
        },
        {
            "name": "張7",
            "age": 24,
            "mobile": "13056781240",
            "sex": "男"
        },
        {
            "name": "張8",
            "age": 25,
            "mobile": "13056781241",
            "sex": "男"
        },
        {
            "name": "張9",
            "age": 26,
            "mobile": "13056781242",
            "sex": "男"
        }
    ],
    "fail": [
        {
            "name": "張1",
            "age": 18,
            "mobile": "3056781234",
            "sex": "男"
        },
        {
            "name": "張10",
            "age": 27,
            "mobile": "130567812436",
            "sex": "男"
        }
    ]
}

方案二的結(jié)果:

{
    "success": [
        {
            "name": "張2",
            "age": 19,
            "mobile": "13056781235",
            "sex": "女"
        },
        {
            "name": "張3",
            "age": 20,
            "mobile": "13056781236",
            "sex": "男"
        },
        {
            "name": "張4",
            "age": 21,
            "mobile": "13056781237",
            "sex": "女"
        },
        {
            "name": "張5",
            "age": 22,
            "mobile": "13056781238",
            "sex": "男"
        },
        {
            "name": "張6",
            "age": 23,
            "mobile": "13056781239",
            "sex": "男"
        },
        {
            "name": "張7",
            "age": 24,
            "mobile": "13056781240",
            "sex": "男"
        },
        {
            "name": "張8",
            "age": 25,
            "mobile": "13056781241",
            "sex": "男"
        },
        {
            "name": "張9",
            "age": 26,
            "mobile": "13056781242",
            "sex": "男"
        }
    ],
    "fail": [
        {
            "name": "張1",
            "age": 18,
            "mobile": "3056781234",
            "sex": "男"
        },
        {
            "name": "張10",
            "age": 27,
            "mobile": "130567812436",
            "sex": "男"
        }
    ]
}

發(fā)現(xiàn)兩種方案的測試結(jié)果雖然是一樣的,但是很明顯,方案二更優(yōu)秀。我們后續(xù)寫代碼的時(shí)候,除了做功能,也要考慮代碼的擴(kuò)展性,不然產(chǎn)品說加個(gè)功能,我們又得吭哧吭哧寫代碼了。

以上就是使用Java實(shí)現(xiàn)Excel導(dǎo)入并進(jìn)行數(shù)據(jù)校驗(yàn)的詳細(xì)內(nèi)容,更多關(guān)于Java Excel導(dǎo)入與數(shù)據(jù)校驗(yàn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring Cloud LoadBalancer 負(fù)載均衡詳解

    Spring Cloud LoadBalancer 負(fù)載均衡詳解

    本文介紹了如何在Spring Cloud中使用SpringCloudLoadBalancer實(shí)現(xiàn)客戶端負(fù)載均衡,并詳細(xì)講解了輪詢策略和隨機(jī)策略的配置方法,此外,還提供了部署到云服務(wù)器并在多個(gè)實(shí)例之間進(jìn)行負(fù)載均衡的步驟,感興趣的朋友一起看看吧
    2025-02-02
  • Java中清空集合列表元素的四種方法

    Java中清空集合列表元素的四種方法

    Java清空列表有多種方式,包括clear()高效直接、創(chuàng)建新列表需注意引用、removeAll需傳入集合、循環(huán)移除效率低,下面就來介紹一下如何實(shí)現(xiàn),感興趣的可以了解一下
    2025-07-07
  • 使用Java實(shí)現(xiàn)對(duì)兩個(gè)秒級(jí)時(shí)間戳相加

    使用Java實(shí)現(xiàn)對(duì)兩個(gè)秒級(jí)時(shí)間戳相加

    在現(xiàn)代應(yīng)用程序開發(fā)中,時(shí)間戳的處理是一個(gè)常見需求,特別是當(dāng)我們需要對(duì)時(shí)間戳進(jìn)行運(yùn)算時(shí),比如時(shí)間戳的相加操作,本文我們將探討如何使用Java對(duì)兩個(gè)秒級(jí)時(shí)間戳進(jìn)行相加,并展示詳細(xì)的代碼示例和運(yùn)行結(jié)果,需要的朋友可以參考下
    2024-08-08
  • mybatis快速入門學(xué)習(xí)教程新手注意問題小結(jié)

    mybatis快速入門學(xué)習(xí)教程新手注意問題小結(jié)

    MyBatis 是支持定制化 SQL、存儲(chǔ)過程以及高級(jí)映射的優(yōu)秀的持久層框架。接下來通過本文給大家介紹mybatis快速入門學(xué)習(xí)教程新手注意問題小結(jié),需要的朋友可以參考下
    2017-02-02
  • Java開發(fā)者就業(yè)需要掌握的9大專業(yè)技能

    Java開發(fā)者就業(yè)需要掌握的9大專業(yè)技能

    這篇文章主要為大家詳細(xì)介紹了java就業(yè)前需要掌握的專業(yè)技能,感興趣的小伙伴們可以參考一下
    2016-09-09
  • spring?boot?redis中的key失效監(jiān)聽的問題解決

    spring?boot?redis中的key失效監(jiān)聽的問題解決

    本文主要介紹了spring?boot?redis中的key失效監(jiān)聽的問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-07-07
  • MyBatis是如何實(shí)現(xiàn)日志模塊的詳解

    MyBatis是如何實(shí)現(xiàn)日志模塊的詳解

    這篇文章主要給大家介紹了關(guān)于MyBatis是如何實(shí)現(xiàn)日志模塊的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用MyBatis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 詳解IDEA2021.2安裝后的配置及重裝問題

    詳解IDEA2021.2安裝后的配置及重裝問題

    這篇文章主要介紹了IDEA2021.2安裝后的配置及重裝,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • Java中String.split()用法小結(jié)

    Java中String.split()用法小結(jié)

    這篇文章主要介紹了Java中String.split()用法小結(jié)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • Java銀行取錢線程安全問題實(shí)例分析

    Java銀行取錢線程安全問題實(shí)例分析

    這篇文章主要介紹了Java銀行取錢線程安全問題,結(jié)合具體實(shí)例形式分析了java使用線程操作模擬銀行取錢的相關(guān)安全問題,需要的朋友可以參考下
    2019-09-09

最新評(píng)論

昂仁县| 通榆县| 绥德县| 准格尔旗| 浦城县| 江永县| 克拉玛依市| 翼城县| 武清区| 商南县| 安岳县| 九寨沟县| 汝阳县| 北宁市| 上杭县| 太谷县| 泸州市| 普格县| 平定县| 万宁市| 屯留县| 灌阳县| 德化县| 丰宁| 额尔古纳市| 正阳县| 嵊州市| 临猗县| 玉龙| 沂水县| 汾西县| 扶沟县| 特克斯县| 蒲江县| 尉犁县| 临江市| 柳河县| 五大连池市| 禄丰县| 汨罗市| 仙居县|