中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

紹興免費(fèi)自助建站鄭州seo外包顧問熱狗

紹興免費(fèi)自助建站,鄭州seo外包顧問熱狗,攝影作品發(fā)布平臺(tái),java二手交易網(wǎng)站開發(fā)遇到問題目錄 背景EasyExcel 問題分析與解決Spring Boot Excel 導(dǎo)入與導(dǎo)出 依賴引入Excel 導(dǎo)入 基本導(dǎo)入功能進(jìn)階導(dǎo)入功能Excel 導(dǎo)出 Excel 導(dǎo)入?yún)?shù)校驗(yàn) 開啟校驗(yàn) 校驗(yàn)規(guī)則定義 Bean Validation 定義校驗(yàn)規(guī)則ExcelValidator 接口定義校驗(yàn)規(guī)則校驗(yàn)結(jié)果接收 異常捕獲接收校驗(yàn)結(jié)果contro…
目錄
  • 背景
  • EasyExcel 問題
  • 分析與解決
  • Spring Boot Excel 導(dǎo)入與導(dǎo)出
    • 依賴引入
    • Excel 導(dǎo)入
      • 基本導(dǎo)入功能
      • 進(jìn)階導(dǎo)入功能
    • Excel 導(dǎo)出
  • Excel 導(dǎo)入?yún)?shù)校驗(yàn)
    • 開啟校驗(yàn)
    • 校驗(yàn)規(guī)則定義
      • Bean Validation 定義校驗(yàn)規(guī)則
      • ExcelValidator 接口定義校驗(yàn)規(guī)則
    • 校驗(yàn)結(jié)果接收
      • 異常捕獲接收校驗(yàn)結(jié)果
      • controller 方法參數(shù)接收校驗(yàn)結(jié)果
  • 總結(jié)

背景

Excel 導(dǎo)入與導(dǎo)出是項(xiàng)目中經(jīng)常用到的功能,在 Java 中常用 poi 實(shí)現(xiàn) Excel 的導(dǎo)入與導(dǎo)出。由于 poi 占用內(nèi)存較大,在高并發(fā)下很容易發(fā)生 OOM 或者頻繁 fullgc,阿里基于 poi 開源了 EasyExcel 項(xiàng)目。

除了節(jié)約內(nèi)存,EasyExcel 還簡化了 API,通過注解映射 Excel 單元格與對(duì)象字段之間的關(guān)系,簡單的幾行代碼就能搞定復(fù)雜的導(dǎo)入導(dǎo)出功能了。

EasyExcel 問題

看似一切美好,不過經(jīng)常做 Excel 導(dǎo)入與導(dǎo)出就會(huì)發(fā)現(xiàn),EasyExcel 還是沒那么完美的。

首先,導(dǎo)入與導(dǎo)出 Excel 本質(zhì)是上將 Excel 文件內(nèi)容與 Java 對(duì)象之間做一個(gè)映射,EasyExcel 做的只是在這兩者之間轉(zhuǎn)換。如果項(xiàng)目中的 Excel 導(dǎo)入與導(dǎo)出功能比較多,會(huì)產(chǎn)生大量的樣板式代碼,使用體驗(yàn)類似于 JDBC。

另外,導(dǎo)入往往還伴隨著校驗(yàn),這是 EasyExcel 沒有支持的功能。如果需要校驗(yàn),要么寫代碼手動(dòng)判斷,要么調(diào)用 Java Validation 規(guī)范 定義的 API 判斷,這又會(huì)產(chǎn)生大量樣板式代碼。

而且,當(dāng)前 spring boot 已經(jīng)成了必備的 Java 開發(fā)框架,easyexcel 也沒有進(jìn)行整合。

分析與解決

導(dǎo)入與導(dǎo)出通常發(fā)生在 Web 環(huán)境,對(duì)于 Spring MVC 來說,可以將請(qǐng)求信息轉(zhuǎn)換為任意類型的 contoller 方法參數(shù),將 controller 方法返回值轉(zhuǎn)換為客戶端支持的內(nèi)容。

如果能夠使用自定義的 controller 方法參數(shù)接收 Excel 文件內(nèi)容,將 controller 方法返回值轉(zhuǎn)換為 Excel 文件響應(yīng),可以直接消除 Excel 導(dǎo)入與導(dǎo)出時(shí)的樣板式代碼。

另外在將請(qǐng)求內(nèi)容轉(zhuǎn)換為 controller 方法參數(shù)時(shí)還可以加入自定義的校驗(yàn)邏輯。

由于 Excel 導(dǎo)入與導(dǎo)出樣板式代碼、校驗(yàn)問題與具體的業(yè)務(wù)邏輯無關(guān),可以單獨(dú)抽象出來,我這里在 EasyExcel 的基礎(chǔ)上封裝了一個(gè) easyexcel-spring-boot-starter 的項(xiàng)目,大大降低了 EasyExcel 上手的門檻,對(duì)用戶來說只需要使用 EasyExcel 定義的注解提供映射關(guān)系就可以了,適用于簡單場景的導(dǎo)入導(dǎo)出。

項(xiàng)目代碼已上傳 github easyexcel-spring-boot-starter 倉庫,點(diǎn)擊鏈接即可查閱。下面就來看看怎樣使用吧。

Spring Boot Excel 導(dǎo)入與導(dǎo)出

依賴引入

首先需要引入依賴,坐標(biāo)如下。

?

1

2

3

4

5

<dependency>

????<groupId>com.zzuhkp</groupId>

????<artifactId>easyexcel-spring-boot-starter</artifactId>

????<version>1.0-SNAPSHOT</version>

</dependency>

不過很不幸的是目前還沒傳至中央倉庫,需要的小伙伴可自行上傳到私有倉庫或直接把代碼嵌入自己的項(xiàng)目。

Excel 導(dǎo)入

首先看下要導(dǎo)入的 Excel 內(nèi)容吧。

為了接收 Excel 文件內(nèi)容,我們需要定義一個(gè)對(duì)應(yīng)的 Model 類。

?

1

2

3

4

5

6

7

8

9

10

11

@Data

public class DemoData {

????@ExcelProperty(index = 0)

????private Integer integer;

????@ExcelProperty(index = 1)

????private String string;

????@ExcelProperty(index = 2)

????private Date date;

}

基本導(dǎo)入功能

然后使用?List<T>?參數(shù)接收即可。

?

1

2

3

4

@PostMapping("/list/obj")

public List<DemoData> listObj(@ExcelParam List<DemoData> list) {

????return list;

}

注意參數(shù)前添加了?@ExcelParam?注解,用來標(biāo)識(shí) Excel 文件參數(shù)。這樣,一個(gè)導(dǎo)入功能實(shí)現(xiàn)了,是不是很簡單呢?

默認(rèn)情況下接收名稱為?file?的表單字段作為 Excel 文件,如果不滿足還可以修改。

?

1

@ExcelParam(value = "file", required = true)

進(jìn)階導(dǎo)入功能

有時(shí)候,我們可能比較關(guān)心對(duì)象對(duì)應(yīng) Excel 的元數(shù)據(jù),例如這個(gè)對(duì)象是第幾行記錄產(chǎn)生的,這個(gè)對(duì)象的字段對(duì)應(yīng) Excel 第幾列,這個(gè)時(shí)候我們可以使用?ReadRows<T>?參數(shù)接收 Excel。

?

1

2

3

4

@PostMapping("/list/rows")

public ReadRows<DemoData> readRows(@ExcelParam ReadRows<DemoData> readRows) {

????return readRows;

}

ReadRows?使用兩個(gè)字段記錄行映射關(guān)系與列映射關(guān)系。

?

1

2

3

4

5

6

public class ReadRows<T> {

????private ExcelReadHeadProperty excelReadHeadProperty;

????private List<ReadRow<T>> rows;

}

ExcelReadHeadProperty?是 EasyExcel 自帶的類,表示列映射關(guān)系的元數(shù)據(jù)。ReadRow?是框架自定義的類,表示行映射關(guān)系的元數(shù)據(jù)。

看下 ReadRow 定義吧。

?

1

2

3

4

5

6

7

8

public class ReadRow<T> {

????// 行索引,從 0 開始

????private final Integer rowIndex;

????// 行記錄對(duì)應(yīng)對(duì)象

????private final T data;

}

使用 ExcelReadHeadProperty 獲取字段對(duì)應(yīng)列索引的示例代碼如下。

?

1

2

3

// 對(duì)象字段名稱 -> 從 0 開始的列索引

Map<String, Integer> fieldColumnIndexMap = readRows.getExcelReadHeadProperty().getHeadMap().values()

????????.stream().collect(Collectors.toMap(Head::getFieldName, Head::getColumnIndex));

Excel 導(dǎo)出

這里對(duì) Excel 的導(dǎo)出進(jìn)行了簡單的支持。將?List<T>?定義為 controller 方法返回值即可。

?

1

2

3

4

5

@ExcelResponse

@GetMapping("/list/download")

public List<DemoData> downloadList() {

????return Arrays.asList(new DemoData(1, "hello", new Date()), new DemoData(2, "excel", new Date()));

}

需要注意的是使用?@ExcelResponse?注解表示響應(yīng)內(nèi)容為 Excel 文件。默認(rèn)情況,下載的文件名稱為?default.xlxs,寫入到名稱為?Sheet1?的工作表中。如果不滿足需求可以修改。

?

1

@ExcelResponse(fileName = "測試文件", sheetName = "工作表1")

Excel 導(dǎo)入?yún)?shù)校驗(yàn)

參數(shù)校驗(yàn)是 Excel 導(dǎo)入常用的功能,這里進(jìn)行了強(qiáng)有力的支持,使用體驗(yàn)如原生 spring boot 校驗(yàn)般順滑。

開啟校驗(yàn)

與 spring boot 原生使用方式一樣,將?@Validated?或?@Valid?注解添加到?@ExcelParam?參數(shù)上即可。

?

1

2

3

4

@PostMapping("/list/obj")

public List<DemoData> listObj(@ExcelParam @Validated List<DemoData> list) {

????return list;

}

校驗(yàn)規(guī)則定義

Bean Validation 定義校驗(yàn)規(guī)則

默認(rèn)情況下框架使用 JSR-303 Bean Validation 規(guī)范定義的校驗(yàn)注解校驗(yàn),需要手動(dòng)引入?spring-boot-starter-validation,可通過設(shè)置環(huán)境變量?easyexcel.validator.default.enable=false?關(guān)閉。

?

1

2

3

4

5

6

7

8

9

@Data

public class DemoData {

????@NotNull(message = "參數(shù)不能為空")

????private Integer integer;

????private String string;

????private Date date;

}

另外還可以自定義注解對(duì)對(duì)象校驗(yàn)。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

... 省略其他元注解

@Constraint(validatedBy = {DemoDataValid.DemoDataValidator.class})

public @interface DemoDataValid {

????????... 省略注解屬性

?????????

????class DemoDataValidator implements ConstraintValidator<DemoDataValid, DemoData> {

????????@Override

????????public boolean isValid(DemoData value, ConstraintValidatorContext context) {

????????????context.disableDefaultConstraintViolation();

????????????context.buildConstraintViolationWithTemplate("測試對(duì)象校驗(yàn)").addConstraintViolation();

????????????return false;

????????}

????}

}

?

1

2

3

4

@DemoDataValid

public class DemoData {

????... 省略屬性

}

ExcelValidator 接口定義校驗(yàn)規(guī)則

Bean Validation 注解只能校驗(yàn)單個(gè)字段或?qū)ο?#xff0c;如果需要對(duì)所有的對(duì)象進(jìn)行校驗(yàn),可以實(shí)現(xiàn)框架定義的?ExcelValidator?接口,然后將實(shí)現(xiàn)定義為 Spring Bean。

這個(gè)接口定義如下。

?

1

2

3

public interface ExcelValidator<T> {

????ExcelValidErrors validate(ReadRows<T> readRows);

}

ExcelValidErrors?用于接收校驗(yàn)的錯(cuò)誤信息,分別使用接口?ExcelValidObjectError?和?ExcelValidFieldError?接口定義行錯(cuò)誤信息和單元格錯(cuò)誤信息。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

public class ExcelValidErrors {

????// 行錯(cuò)誤信息或單元格錯(cuò)誤信息列表

????private final List<ExcelValidObjectError> errors;

}

public interface ExcelValidObjectError {

????// 獲取行號(hào),從 1 開始

????Integer getRow();

????// 獲取錯(cuò)誤消息

????String getMessage();

}

public interface ExcelValidFieldError extends ExcelValidObjectError {

????// 獲取列,從 1 開始

????Integer getColumn();

}

例如,如果需要對(duì)所有的?DemoData?校驗(yàn)?integer?字段的值不能重復(fù),可以使用如下的代碼。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

@Component

public class CustomExcelValidator implements ExcelValidator<DemoData> {

????@Override

????public ExcelValidErrors validate(ReadRows<DemoData> readRows) {

????????ExcelValidErrors errors = new ExcelValidErrors();

????????Map<Integer, List<ReadRow<DemoData>>> group = readRows.getRows().stream()

????????????????.collect(Collectors.groupingBy(item -> item.getData().getInteger()));

????????for (Map.Entry<Integer, List<ReadRow<DemoData>>> entry : group.entrySet()) {

????????????if (entry.getValue().size() > 1) {

????????????????for (ReadRow<DemoData> readRow : entry.getValue()) {

????????????????????errors.addError(new DefaultExcelObjectError(readRow.getRowIndex() + 1, "參數(shù)重復(fù)"));

????????????????}

????????????}

????????}

????????return errors;

????}

}

校驗(yàn)結(jié)果接收

與 Spring MVC 設(shè)計(jì)類似,這里也提供了兩種接收校驗(yàn)結(jié)果的方式。

異常捕獲接收校驗(yàn)結(jié)果

開啟校驗(yàn)后,如果校驗(yàn)結(jié)果中包含錯(cuò)誤,會(huì)將錯(cuò)誤信息封裝到?ExcelValidException,并拋出異常,可以通過全局異常捕獲的方式收集錯(cuò)誤信息。

?

1

2

3

4

5

6

7

8

@RestControllerAdvice

public class GlobalExceptionControllerAdvice {

????@ExceptionHandler(ExcelValidException.class)

????public String handleException(ExcelValidException e) {

????????ExcelValidErrors errors = e.getErrors();

????????return JSON.toJSONString(errors);

????}

}

controller 方法參數(shù)接收校驗(yàn)結(jié)果

如果不想通過異常捕獲的方式接收校驗(yàn)的錯(cuò)誤信息,還可以將錯(cuò)誤信息添加到?@ExcelParam?參數(shù)的后面,示例代碼如下。

?

1

2

3

4

5

6

7

8

@PostMapping("/list/obj")

public List<DemoData> listObj(@ExcelParam @Validated List<DemoData> list, ExcelValidErrors errors) {

????if (errors.hasErrors()) {

????????String messages = errors.getAllErrors().stream().map(ExcelValidObjectError::getMessage).collect(Collectors.joining(" | "));

????????throw new RuntimeException("發(fā)現(xiàn)異常:" + messages);

????}

????return list;

}

總結(jié)

easyexcel-spring-boot-starter 綜合應(yīng)用了前面文章介紹的各種 Spring 知識(shí),代碼量并不大,對(duì)實(shí)現(xiàn)感興趣的小伙伴可自行查閱代碼。由于這個(gè)框架是把 Excel 中所有的行數(shù)據(jù)收集到內(nèi)存,因此只適合一些比較簡單的場景。

http://www.risenshineclean.com/news/49356.html

相關(guān)文章:

  • 做網(wǎng)站用到的單詞關(guān)鍵詞seo優(yōu)化公司
  • 浙江省建設(shè)廳網(wǎng)站地址廣州網(wǎng)站優(yōu)化服務(wù)
  • 醫(yī)院網(wǎng)站建設(shè)要求seo自學(xué)網(wǎng)免費(fèi)
  • 怎么能讓網(wǎng)站排名靠前百度站長平臺(tái)快速收錄
  • 泰州網(wǎng)站建設(shè)服務(wù)熱線寧德市委書記
  • 傳奇網(wǎng)站傳奇寧波優(yōu)化seo是什么
  • 紹興建站模板系統(tǒng)網(wǎng)站關(guān)鍵詞如何快速上首頁
  • 自己做圖片網(wǎng)站競價(jià)排名服務(wù)
  • 網(wǎng)站上傳不了照片市場調(diào)研方法有哪幾種
  • 網(wǎng)站建設(shè)與制作考試題電商運(yùn)營培訓(xùn)
  • 貿(mào)易公司做網(wǎng)站有用嗎搭建一個(gè)網(wǎng)站需要多少錢
  • 網(wǎng)站圖片代碼怎么做免費(fèi)網(wǎng)站建站
  • 網(wǎng)站開發(fā)畢設(shè)開題報(bào)告怎么寫國內(nèi)手機(jī)搜索引擎十大排行
  • wordpress滾軸式主題網(wǎng)站如何優(yōu)化一個(gè)關(guān)鍵詞
  • 動(dòng)態(tài)網(wǎng)站建設(shè)的心得體會(huì)個(gè)人網(wǎng)站設(shè)計(jì)畢業(yè)論文
  • 當(dāng)今做那些網(wǎng)站致富seo交流論壇
  • php企業(yè)網(wǎng)站源碼推薦被逆冬seo課程欺騙了
  • 網(wǎng)站流量查詢平臺(tái)nba賽程排名
  • 網(wǎng)站制作用到什么技術(shù)seo怎么發(fā)文章 seo發(fā)布工具
  • 濟(jì)南網(wǎng)站開發(fā) blog網(wǎng)站源碼下載
  • 青島seo做的好的網(wǎng)站程序員培訓(xùn)班要多少錢
  • 幼兒園主題網(wǎng)絡(luò)圖設(shè)計(jì)感想seo優(yōu)化系統(tǒng)
  • 做網(wǎng)站有年費(fèi)嗎線上如何推廣自己的產(chǎn)品
  • 裝修公司做網(wǎng)站熱門關(guān)鍵詞網(wǎng)絡(luò)廣告的形式有哪些?
  • asp net做購物網(wǎng)站合肥疫情最新消息
  • 廣州智能建站模板百度推廣客戶端手機(jī)版
  • 浙江網(wǎng)站備案加急域名注冊(cè)商
  • h5網(wǎng)站怎么做api對(duì)接關(guān)鍵詞seo深圳
  • 有沒有美國做天然酵母的網(wǎng)站深圳純手工seo
  • 收費(fèi)視頻網(wǎng)站怎么做b2b免費(fèi)發(fā)布平臺(tái)